From 7cc2ed78ddf20843f7cc3da481636009ff428dde Mon Sep 17 00:00:00 2001 From: Xavier Fournet Date: Wed, 15 Aug 2012 14:03:36 +0200 Subject: [PATCH 01/15] [IDEA-91145] Merge maven-embedder-1.1-SNAPSHOT into maven2-server-impl --- .../maven-embedder-1.1-SNAPSHOT-sources.jar | Bin 12269 -> 0 bytes .../lib/maven-embedder-1.1-SNAPSHOT.jar | Bin 23104 -> 0 bytes .../maven2-server-impl/maven2-server-impl.iml | 11 - .../maven/embedder/AbstractMavenLogger.java | 114 ++++ .../maven/embedder/FieldAccessor.java | 54 ++ .../maven/embedder/MavenEmbedder.java | 577 ++++++++++++++++++ .../maven/embedder/MavenEmbedderLog.java | 76 +++ .../maven/embedder/MavenEmbedderLogger.java | 31 + .../maven/embedder/MavenEmbedderSettings.java | 151 +++++ .../maven/embedder/MavenExecutionResult.java | 44 ++ .../maven/embedder/NullMavenLogger.java | 12 + .../embedder/PlexusComponentConfigurator.java | 13 + 12 files changed, 1072 insertions(+), 11 deletions(-) delete mode 100644 plugins/maven/maven2-server-impl/lib-src/maven-embedder-1.1-SNAPSHOT-sources.jar delete mode 100644 plugins/maven/maven2-server-impl/lib/maven-embedder-1.1-SNAPSHOT.jar create mode 100644 plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/AbstractMavenLogger.java create mode 100644 plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/FieldAccessor.java create mode 100644 plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/MavenEmbedder.java create mode 100644 plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/MavenEmbedderLog.java create mode 100644 plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/MavenEmbedderLogger.java create mode 100644 plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/MavenEmbedderSettings.java create mode 100644 plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/MavenExecutionResult.java create mode 100644 plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/NullMavenLogger.java create mode 100644 plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/PlexusComponentConfigurator.java diff --git a/plugins/maven/maven2-server-impl/lib-src/maven-embedder-1.1-SNAPSHOT-sources.jar b/plugins/maven/maven2-server-impl/lib-src/maven-embedder-1.1-SNAPSHOT-sources.jar deleted file mode 100644 index 041fce01bc86fb45e7db6350ff72bda9e8827d87..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12269 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 diff --git a/plugins/maven/maven2-server-impl/lib/maven-embedder-1.1-SNAPSHOT.jar b/plugins/maven/maven2-server-impl/lib/maven-embedder-1.1-SNAPSHOT.jar deleted file mode 100644 index c08b985459fba1072173ccd85a137e1d064cc709..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23104 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 - - - - - - - - - - - diff --git a/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/AbstractMavenLogger.java b/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/AbstractMavenLogger.java new file mode 100644 index 000000000000..b166d1ea5d6b --- /dev/null +++ b/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/AbstractMavenLogger.java @@ -0,0 +1,114 @@ +/* ========================================================================== + * Copyright 2006 Mevenide Team + * + * 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.maven.embedder; + +import org.codehaus.plexus.logging.Logger; + +public abstract class AbstractMavenLogger implements Logger { + private static final String LINE_SEPARATOR = System.getProperty("line.separator"); + + private int myThreshold; + + private void doPrint(int level, String message, Throwable throwable) { + if (level < myThreshold) return; + + if (!message.endsWith(LINE_SEPARATOR)) { + message += LINE_SEPARATOR; + } + + printMessage(level, message, throwable); + } + + protected abstract void printMessage(int level, String message, Throwable throwable); + + public void debug(String string, Throwable throwable) { + doPrint(LEVEL_DEBUG, string, throwable); + } + + public void info(String string, Throwable throwable) { + doPrint(LEVEL_INFO, string, throwable); + } + + public void warn(String string, Throwable throwable) { + doPrint(LEVEL_WARN, string, throwable); + } + + public void error(String string, Throwable throwable) { + doPrint(LEVEL_ERROR, string, throwable); + } + + public void fatalError(String string, Throwable throwable) { + doPrint(LEVEL_FATAL, string, throwable); + } + + public void debug(String message) { + debug(message, null); + } + + public boolean isDebugEnabled() { + return getThreshold() <= LEVEL_DEBUG; + } + + public void info(String message) { + info(message, null); + } + + public boolean isInfoEnabled() { + return getThreshold() <= LEVEL_INFO; + } + + public void warn(String message) { + warn(message, null); + } + + public boolean isWarnEnabled() { + return getThreshold() <= LEVEL_WARN; + } + + public void error(String message) { + error(message, null); + } + + public boolean isErrorEnabled() { + return getThreshold() <= LEVEL_ERROR; + } + + public void fatalError(String message) { + fatalError(message, null); + } + + public boolean isFatalErrorEnabled() { + return getThreshold() <= LEVEL_FATAL; + } + + public void setThreshold(int threshold) { + this.myThreshold = threshold; + } + + public int getThreshold() { + return myThreshold; + } + + public Logger getChildLogger(String s) { + return null; + } + + public String getName() { + return toString(); + } +} diff --git a/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/FieldAccessor.java b/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/FieldAccessor.java new file mode 100644 index 000000000000..90255d1320df --- /dev/null +++ b/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/FieldAccessor.java @@ -0,0 +1,54 @@ +/* + * Copyright 2000-2009 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.maven.embedder; + +import java.lang.reflect.Field; + +class FieldAccessor { + private volatile FIELD_TYPE myWagonManagerCache; + private final Class myHostClass; + private final Object myHost; + private final String myFieldName; + + public FieldAccessor(Class hostClass, T host, String fieldName) { + myHostClass = hostClass; + myHost = host; + myFieldName = fieldName; + } + + public FIELD_TYPE getField() { + if (myWagonManagerCache == null) { + Object value = getFieldValue(myHostClass, myFieldName, myHost); + //noinspection unchecked + myWagonManagerCache = (FIELD_TYPE)value; + } + return myWagonManagerCache; + } + + private Object getFieldValue(Class c, String fieldName, Object o) { + try { + Field f = c.getDeclaredField(fieldName); + f.setAccessible(true); + return f.get(o); + } + catch (NoSuchFieldException e) { + throw new RuntimeException(e); + } + catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file diff --git a/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/MavenEmbedder.java b/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/MavenEmbedder.java new file mode 100644 index 000000000000..3fa0fa4762bd --- /dev/null +++ b/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/MavenEmbedder.java @@ -0,0 +1,577 @@ +/* + * Copyright 2000-2009 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.maven.embedder; + +import org.apache.maven.DefaultMaven; +import org.apache.maven.Maven; +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.factory.ArtifactFactory; +import org.apache.maven.artifact.handler.ArtifactHandler; +import org.apache.maven.artifact.handler.manager.ArtifactHandlerManager; +import org.apache.maven.artifact.manager.DefaultWagonManager; +import org.apache.maven.artifact.manager.WagonManager; +import org.apache.maven.artifact.metadata.ArtifactMetadataSource; +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.artifact.repository.ArtifactRepositoryFactory; +import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy; +import org.apache.maven.artifact.repository.DefaultArtifactRepository; +import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout; +import org.apache.maven.artifact.resolver.*; +import org.apache.maven.execution.DefaultMavenExecutionRequest; +import org.apache.maven.execution.MavenExecutionRequest; +import org.apache.maven.execution.ReactorManager; +import org.apache.maven.extension.ExtensionManager; +import org.apache.maven.model.Extension; +import org.apache.maven.model.Plugin; +import org.apache.maven.monitor.event.DefaultEventDispatcher; +import org.apache.maven.monitor.event.DefaultEventMonitor; +import org.apache.maven.monitor.event.EventDispatcher; +import org.apache.maven.plugin.PluginManager; +import org.apache.maven.profiles.DefaultProfileManager; +import org.apache.maven.profiles.ProfileManager; +import org.apache.maven.project.MavenProject; +import org.apache.maven.project.MavenProjectBuilder; +import org.apache.maven.project.ProjectBuilderConfiguration; +import org.apache.maven.project.interpolation.ModelInterpolationException; +import org.apache.maven.settings.*; +import org.codehaus.classworlds.ClassWorld; +import org.codehaus.plexus.DefaultPlexusContainer; +import org.codehaus.plexus.PlexusContainer; +import org.codehaus.plexus.PlexusContainerException; +import org.codehaus.plexus.component.repository.ComponentDescriptor; +import org.codehaus.plexus.component.repository.exception.ComponentLookupException; +import org.codehaus.plexus.logging.BaseLoggerManager; +import org.codehaus.plexus.logging.Logger; +import org.codehaus.plexus.util.xml.Xpp3Dom; +import org.codehaus.plexus.util.xml.pull.XmlPullParserException; +import org.jetbrains.annotations.NotNull; +import org.sonatype.plexus.components.sec.dispatcher.SecDispatcher; +import org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.*; + +public class MavenEmbedder { + private static final String PROP_MAVEN_HOME = "maven.home"; + + private final DefaultPlexusContainer myContainer; + private final Settings mySettings; + private final Logger myLogger; + private final MavenEmbedderSettings myEmbedderSettings; + private final ArtifactRepository myLocalRepository; + + private MavenEmbedder(@NotNull DefaultPlexusContainer container, + @NotNull Settings settings, + @NotNull Logger logger, + @NotNull MavenEmbedderSettings embedderSettings) { + myContainer = container; + mySettings = settings; + myLogger = logger; + myEmbedderSettings = embedderSettings; + myLocalRepository = createLocalRepository(embedderSettings); + + loadSettings(); + } + + private void loadSettings() { + // copied from DefaultMaven.resolveParameters + // copied because using original code spoils something in the container and configuration are get messed and not picked up. + WagonManager wagonManager = getComponent(WagonManager.class); + + wagonManager.setOnline(!mySettings.isOffline()); + + if (wagonManager instanceof DefaultWagonManager) { + ((DefaultWagonManager)wagonManager).setHttpUserAgent("Apache-Maven/2.2"); + } + + Proxy proxy = mySettings.getActiveProxy(); + if (proxy != null && proxy.getHost() != null) { + String pass = decrypt(proxy.getPassword()); + wagonManager.addProxy(proxy.getProtocol(), proxy.getHost(), proxy.getPort(), proxy.getUsername(), pass, proxy.getNonProxyHosts()); + } + + for (Object each : mySettings.getServers()) { + Server server = (Server)each; + + String passWord = decrypt(server.getPassword()); + String passPhrase = decrypt(server.getPassphrase()); + + wagonManager.addAuthenticationInfo(server.getId(), server.getUsername(), passWord, server.getPrivateKey(), passPhrase); + + wagonManager.addPermissionInfo(server.getId(), server.getFilePermissions(), server.getDirectoryPermissions()); + + if (server.getConfiguration() != null) { + wagonManager.addConfiguration(server.getId(), (Xpp3Dom)server.getConfiguration()); + } + } + + for (Object each : mySettings.getMirrors()) { + Mirror mirror = (Mirror)each; + if (mirror.getUrl() == null) continue; + wagonManager.addMirror(mirror.getId(), mirror.getMirrorOf(), mirror.getUrl()); + } + // end copied from DefaultMaven.resolveParameters + } + + private String decrypt(String pass) { + try { + pass = getComponent(SecDispatcher.class, "maven").decrypt(pass); + } + catch (SecDispatcherException e) { + MavenEmbedderLog.LOG.warn(e); + } + return pass; + } + + private ArtifactRepository createLocalRepository(MavenEmbedderSettings generalSettings) { + ArtifactRepositoryLayout layout = getComponent(ArtifactRepositoryLayout.class, "default"); + ArtifactRepositoryFactory factory = getComponent(ArtifactRepositoryFactory.class); + + String url = mySettings.getLocalRepository(); + if (!url.startsWith("file:")) url = "file://" + url; + + ArtifactRepository localRepository = new DefaultArtifactRepository("local", url, layout); + + boolean snapshotPolicySet = mySettings.isOffline(); + if (!snapshotPolicySet && generalSettings.getSnapshotUpdatePolicy() == MavenEmbedderSettings.UpdatePolicy.ALWAYS_UPDATE) { + factory.setGlobalUpdatePolicy(ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS); + } + factory.setGlobalChecksumPolicy(ArtifactRepositoryPolicy.CHECKSUM_POLICY_WARN); + + return localRepository; + } + + @NotNull + public ArtifactRepository getLocalRepository() { + return myLocalRepository; + } + + @NotNull + public File getLocalRepositoryFile() { + return new File(myLocalRepository.getBasedir()); + } + + public Settings getSettings() { + return mySettings; + } + + @NotNull + public MavenExecutionResult resolveProject(@NotNull final File file, @NotNull final List activeProfiles) { + return resolveProject(file, activeProfiles, Collections.emptyList()); + } + + @NotNull + public MavenExecutionResult resolveProject(@NotNull final File file, + @NotNull final List activeProfiles, + List listeners) { + MavenExecutionRequest request = createRequest(file, activeProfiles, Collections.emptyList(), Collections.emptyList()); + ProjectBuilderConfiguration config = request.getProjectBuilderConfiguration(); + + request.getGlobalProfileManager().loadSettingsProfiles(mySettings); + + ProfileManager globalProfileManager = request.getGlobalProfileManager(); + globalProfileManager.loadSettingsProfiles(request.getSettings()); + + List exceptions = new ArrayList(); + MavenProject project = null; + try { + // copied from DefaultMavenProjectBuilder.buildWithDependencies + MavenProjectBuilder builder = getComponent(MavenProjectBuilder.class); + project = builder.build(new File(file.getPath()), config); + builder.calculateConcreteState(project, config, false); + + // copied from DefaultLifecycleExecutor.execute + findExtensions(project); + // end copied from DefaultLifecycleExecutor.execute + + Artifact projectArtifact = project.getArtifact(); + Map managedVersions = project.getManagedVersionMap(); + ArtifactMetadataSource metadataSource = getComponent(ArtifactMetadataSource.class); + project.setDependencyArtifacts(project.createArtifacts(getComponent(ArtifactFactory.class), null, null)); + + ArtifactResolver resolver = getComponent(ArtifactResolver.class); + ArtifactResolutionResult result = resolver + .resolveTransitively(project.getDependencyArtifacts(), projectArtifact, managedVersions, myLocalRepository, + project.getRemoteArtifactRepositories(), metadataSource, null, listeners); + project.setArtifacts(result.getArtifacts()); + // end copied from DefaultMavenProjectBuilder.buildWithDependencies + } + catch (Exception e) { + return handleException(e); + } + + return new MavenExecutionResult(project, exceptions); + } + + private void findExtensions(MavenProject project) { + // end copied from DefaultLifecycleExecutor.findExtensions + ExtensionManager extensionManager = getComponent(ExtensionManager.class); + for (Object each : project.getBuildExtensions()) { + try { + extensionManager.addExtension((Extension)each, project, myLocalRepository); + } + catch (PlexusContainerException e) { + MavenEmbedderLog.LOG.error(e); + } + catch (ArtifactResolutionException e) { + MavenEmbedderLog.LOG.error(e); + } + catch (ArtifactNotFoundException e) { + MavenEmbedderLog.LOG.error(e); + } + } + extensionManager.registerWagons(); + + Map handlers = findArtifactTypeHandlers(project); + getComponent(ArtifactHandlerManager.class).addHandlers(handlers); + } + + @SuppressWarnings({"unchecked"}) + private Map findArtifactTypeHandlers(MavenProject project) { + // end copied from DefaultLifecycleExecutor.findExtensions + Map result = new HashMap(); + for (Object each : project.getBuildPlugins()) { + Plugin eachPlugin = (Plugin)each; + + if (eachPlugin.isExtensions()) { + try { + PluginManager pluginManager = getComponent(PluginManager.class); + pluginManager.verifyPlugin(eachPlugin, project, mySettings, myLocalRepository); + result.putAll(pluginManager.getPluginComponents(eachPlugin, ArtifactHandler.ROLE)); + } + catch (Exception e) { + MavenEmbedderLog.LOG.info(e); + continue; + } + + for (Object o : result.values()) { + ArtifactHandler handler = (ArtifactHandler)o; + if (project.getPackaging().equals(handler.getPackaging())) { + project.getArtifact().setArtifactHandler(handler); + } + } + } + } + return result; + } + + public void resolve(@NotNull final Artifact artifact, @NotNull final List repos) + throws ArtifactResolutionException, ArtifactNotFoundException { + getComponent(ArtifactResolver.class).resolve(artifact, repos, myLocalRepository); + } + + public Set resolveTransitively(@NotNull Set toResolve, @NotNull List repos) + throws ArtifactResolutionException, ArtifactNotFoundException { + Artifact project = getComponent(ArtifactFactory.class).createBuildArtifact("temp", "temp", "666", "pom"); + + return getComponent(ArtifactResolver.class) + .resolveTransitively(toResolve, project, Collections.EMPTY_MAP, myLocalRepository, repos, getComponent(ArtifactMetadataSource.class)) + .getArtifacts(); + } + + @NotNull + public MavenExecutionResult execute(@NotNull final File file, + @NotNull final List activeProfiles, + @NotNull final List goals) { + try { + MavenExecutionRequest request = createRequest(file, activeProfiles, Collections.emptyList(), goals); + Maven maven = getComponent(Maven.class); + Method method = maven.getClass().getDeclaredMethod("doExecute", MavenExecutionRequest.class, EventDispatcher.class); + method.setAccessible(true); + ReactorManager reactor = (ReactorManager)method.invoke(maven, request, request.getEventDispatcher()); + return new MavenExecutionResult(reactor.getTopLevelProject(), Collections.emptyList()); + } + catch (InvocationTargetException e) { + return handleException(e.getTargetException()); + } + catch (NoSuchMethodException e) { + throw new RuntimeException(e); // should never happen + } + catch (IllegalAccessException e) { + throw new RuntimeException(e); // should never happen + } + } + + @NotNull + public MavenExecutionResult readProjectWithModules(@NotNull final File file, List activeProfiles, List inactiveProfiles) { + MavenExecutionRequest request = createRequest(file, activeProfiles, inactiveProfiles, Collections.emptyList()); + request.getGlobalProfileManager().loadSettingsProfiles(mySettings); + request.setRecursive(true); + + return readProject(request); + } + + @NotNull + private MavenExecutionResult readProject(@NotNull final MavenExecutionRequest request) { + ProfileManager globalProfileManager = request.getGlobalProfileManager(); + globalProfileManager.loadSettingsProfiles(request.getSettings()); + + MavenProject rootProject = null; + final List exceptions = new ArrayList(); + Object result = null; + try { + final File pomFile = new File(request.getPomFile()); + if (!pomFile.exists()) { + throw new FileNotFoundException("File doesn't exist: " + pomFile.getPath()); + } + + final Method getProjectsMethod = DefaultMaven.class.getDeclaredMethod("getProjects", MavenExecutionRequest.class); + getProjectsMethod.setAccessible(true); + Maven maven = getComponent(Maven.class); + result = getProjectsMethod.invoke(maven, request); + } + catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } + catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + catch (InvocationTargetException e) { + return handleException(e.getTargetException()); + } + catch (Exception e) { + return handleException(e); + } + + if (result != null) { + MavenProjectBuilder builder = getComponent(MavenProjectBuilder.class); + for (Object p : (List)result) { + MavenProject project = (MavenProject)p; + try { + builder.calculateConcreteState(project, request.getProjectBuilderConfiguration(), false); + } + catch (ModelInterpolationException e) { + exceptions.add(e); + } + + if (project.isExecutionRoot()) { + rootProject = project; + } + } + + if (rootProject == null && exceptions.isEmpty()) { + throw new RuntimeException("Could't build project for unknown reason"); + } + } + + return new MavenExecutionResult(rootProject, exceptions); + } + + @NotNull + public MavenExecutionResult readProject(@NotNull final File file, + @NotNull final List activeProfiles, + @NotNull final List inactiveProfiles) { + MavenExecutionRequest request = createRequest(file, activeProfiles, inactiveProfiles, Collections.emptyList()); + request.getGlobalProfileManager().loadSettingsProfiles(mySettings); + request.setRecursive(false); + + return readProject(request); + } + + private MavenExecutionRequest createRequest(File file, List activeProfiles, List inactiveProfiles, List goals) { + Properties executionProperties = myEmbedderSettings.getProperties(); + if (executionProperties == null) executionProperties = new Properties(); + + DefaultEventDispatcher dispatcher = new DefaultEventDispatcher(); + dispatcher.addEventMonitor(new DefaultEventMonitor(myLogger)); + + // subclassing because in DefaultMavenExecutionRequest field isRecursive is always false + MavenExecutionRequest result = new DefaultMavenExecutionRequest(myLocalRepository, mySettings, dispatcher, goals, file.getParent(), + createProfileManager(activeProfiles, inactiveProfiles, + executionProperties), executionProperties, + new Properties(), true) { + private boolean myIsRecursive; + + @Override + public boolean isRecursive() { + return myIsRecursive; + } + + @Override + public void setRecursive(final boolean recursive) { + myIsRecursive = recursive; + } + }; + + result.setPomFile(file.getPath()); + result.setRecursive(myEmbedderSettings.isRecursive()); + + return result; + } + + private MavenExecutionResult handleException(Throwable e) { + if (e instanceof RuntimeException) throw (RuntimeException)e; + if (e instanceof Error) throw (Error)e; + + return new MavenExecutionResult(null, Collections.singletonList((Exception)e)); + } + + private ProfileManager createProfileManager(List activeProfiles, List inactiveProfiles, Properties executionProperties) { + ProfileManager profileManager = new DefaultProfileManager(getContainer(), executionProperties); + profileManager.explicitlyActivate(activeProfiles); + profileManager.explicitlyDeactivate(inactiveProfiles); + return profileManager; + } + + @SuppressWarnings({"unchecked"}) + public T getComponent(Class clazz) { + try { + return (T)getContainer().lookup(clazz.getName()); + } + catch (ComponentLookupException e) { + throw new RuntimeException(e); + } + } + + @SuppressWarnings({"unchecked"}) + public T getComponent(Class clazz, String roleHint) { + try { + return (T)getContainer().lookup(clazz.getName(), roleHint); + } + catch (ComponentLookupException e) { + throw new RuntimeException(e); + } + } + + public PlexusContainer getContainer() { + return myContainer; + } + + public void release() { + releaseResolverThreadExecutor(); + myContainer.dispose(); + } + + private void releaseResolverThreadExecutor() { + ArtifactResolver resolver = getComponent(ArtifactResolver.class); + @SuppressWarnings({"unchecked"}) FieldAccessor pool = new FieldAccessor(DefaultArtifactResolver.class, resolver, "resolveArtifactPool"); + try { + final Object threadPool = pool.getField(); // an instance of a hidden copy of ThreadPoolExecutor + threadPool.getClass().getMethod("shutdown").invoke(threadPool); + } + catch (RuntimeException e) { + throw e; + } + catch (Exception e) { + throw new RuntimeException(e); + } + } + + @NotNull + public static MavenEmbedder create(@NotNull final MavenEmbedderSettings embedderSettings) { + @NotNull final Logger logger = getLogger(embedderSettings); + + DefaultPlexusContainer container = new DefaultPlexusContainer(); + container.setClassWorld(new ClassWorld("plexus.core", embedderSettings.getClass().getClassLoader())); + container.setLoggerManager(new BaseLoggerManager() { + @Override + protected Logger createLogger(final String s) { + return logger; + } + }); + + try { + container.initialize(); + container.start(); + } + catch (PlexusContainerException e) { + MavenEmbedderLog.LOG.error(e); + throw new RuntimeException(e); + } + + final PlexusComponentConfigurator configurator = embedderSettings.getConfigurator(); + if (configurator != null) { + configurator.configureComponents(container); + } + + File mavenHome = embedderSettings.getMavenHome(); + if (mavenHome != null) { + System.setProperty(PROP_MAVEN_HOME, mavenHome.getPath()); + } + + Settings nativeSettings = buildSettings(container, embedderSettings); + + return new MavenEmbedder(container, nativeSettings, logger, embedderSettings); + } + + @NotNull + private static Logger getLogger(@NotNull final MavenEmbedderSettings embedderSettings) { + final Logger logger = embedderSettings.getLogger(); + return logger != null ? logger : new NullMavenLogger(); + } + + public static Settings buildSettings(PlexusContainer container, MavenEmbedderSettings embedderSettings) { + File file = embedderSettings.getGlobalSettingsFile(); + if (file != null) { + System.setProperty(MavenSettingsBuilder.ALT_GLOBAL_SETTINGS_XML_LOCATION, file.getPath()); + } + + Settings settings = null; + + try { + MavenSettingsBuilder builder = (MavenSettingsBuilder)container.lookup(MavenSettingsBuilder.ROLE); + + File userSettingsFile = embedderSettings.getUserSettingsFile(); + if (userSettingsFile != null && userSettingsFile.exists() && !userSettingsFile.isDirectory()) { + settings = builder.buildSettings(userSettingsFile, false); + } + + if (settings == null) { + settings = builder.buildSettings(); + } + } + catch (ComponentLookupException e) { + MavenEmbedderLog.LOG.error(e); + } + catch (IOException e) { + MavenEmbedderLog.LOG.warn(e); + } + catch (XmlPullParserException e) { + MavenEmbedderLog.LOG.warn(e); + } + + if (settings == null) { + settings = new Settings(); + } + + if (embedderSettings.getLocalRepository() != null) { + settings.setLocalRepository(embedderSettings.getLocalRepository().getPath()); + } + if (settings.getLocalRepository() == null) { + settings.setLocalRepository(System.getProperty("user.home") + "/.m2/repository"); + } + + settings.setOffline(embedderSettings.isWorkOffline()); + settings.setInteractiveMode(false); + settings.setUsePluginRegistry(embedderSettings.isUsePluginRegistry()); + + RuntimeInfo runtimeInfo = new RuntimeInfo(settings); + runtimeInfo.setPluginUpdateOverride(embedderSettings.getPluginUpdatePolicy() == MavenEmbedderSettings.UpdatePolicy.ALWAYS_UPDATE); + settings.setRuntimeInfo(runtimeInfo); + + return settings; + } + + public static void setImplementation(PlexusContainer container, Class componentClass, Class implementationClass) { + ComponentDescriptor d = container.getComponentDescriptor(componentClass.getName()); + d.setImplementation(implementationClass.getName()); + } +} + diff --git a/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/MavenEmbedderLog.java b/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/MavenEmbedderLog.java new file mode 100644 index 000000000000..78cb538f928b --- /dev/null +++ b/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/MavenEmbedderLog.java @@ -0,0 +1,76 @@ +/* + * Copyright 2000-2009 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.maven.embedder; + +import org.jetbrains.annotations.NotNull; + +public class MavenEmbedderLog { + public static final MavenEmbedderLogger LOG = new MavenEmbedderLogger() { + public void debug(final CharSequence msg) { + if (ourDelegate != null) ourDelegate.debug(msg); + } + + public void debug(final CharSequence msg, final Throwable e) { + if (ourDelegate != null) ourDelegate.debug(msg, e); + } + + public void debug(final Throwable e) { + if (ourDelegate != null) ourDelegate.debug(e); + } + + public void info(final CharSequence msg) { + if (ourDelegate != null) ourDelegate.info(msg); + } + + public void info(final CharSequence msg, final Throwable e) { + if (ourDelegate != null) ourDelegate.info(msg, e); + } + + public void info(final Throwable e) { + if (ourDelegate != null) ourDelegate.info(e); + } + + public void warn(final CharSequence msg) { + if (ourDelegate != null) ourDelegate.warn(msg); + } + + public void warn(final CharSequence msg, final Throwable e) { + if (ourDelegate != null) ourDelegate.warn(msg, e); + } + + public void warn(final Throwable e) { + if (ourDelegate != null) ourDelegate.warn(e); + } + + public void error(final CharSequence msg) { + if (ourDelegate != null) ourDelegate.error(msg); + } + + public void error(final CharSequence msg, final Throwable e) { + if (ourDelegate != null) ourDelegate.error(msg, e); + } + + public void error(final Throwable e) { + if (ourDelegate != null) ourDelegate.error(e); + } + }; + + private static MavenEmbedderLogger ourDelegate = null; + + public void setLogger(@NotNull final MavenEmbedderLogger logger) { + ourDelegate = logger; + } +} diff --git a/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/MavenEmbedderLogger.java b/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/MavenEmbedderLogger.java new file mode 100644 index 000000000000..8205236b2b69 --- /dev/null +++ b/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/MavenEmbedderLogger.java @@ -0,0 +1,31 @@ +package org.jetbrains.maven.embedder; + +/** + * @author Sergey.Anchipolevsky + * Date: 27.01.2010 + */ +public interface MavenEmbedderLogger { + void debug(CharSequence msg); + + void debug(CharSequence msg, Throwable e); + + void debug(Throwable e); + + void info(CharSequence msg); + + void info(CharSequence msg, Throwable e); + + void info(Throwable e); + + void warn(CharSequence msg); + + void warn(CharSequence msg, Throwable e); + + void warn(Throwable e); + + void error(CharSequence msg); + + void error(CharSequence msg, Throwable e); + + void error(Throwable e); +} diff --git a/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/MavenEmbedderSettings.java b/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/MavenEmbedderSettings.java new file mode 100644 index 000000000000..0e9c51c3c083 --- /dev/null +++ b/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/MavenEmbedderSettings.java @@ -0,0 +1,151 @@ +/* + * Copyright 2000-2009 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.maven.embedder; + +import org.codehaus.plexus.logging.Logger; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.io.File; +import java.util.Properties; + +public class MavenEmbedderSettings { + public enum UpdatePolicy { + ALWAYS_UPDATE, DO_NOT_UPDATE + } + + private boolean workOffline = false; + private boolean isRecursive = true; + private File mavenHome; + private File userSettingsFile; + private File globalSettingsFile; + private File localRepository; + private boolean usePluginRegistry = false; + private UpdatePolicy snapshotUpdatePolicy = UpdatePolicy.ALWAYS_UPDATE; + private UpdatePolicy pluginUpdatePolicy = UpdatePolicy.DO_NOT_UPDATE; + private Properties myProperties; + + @Nullable + private Logger myLogger; + @Nullable + private PlexusComponentConfigurator myConfigurator; + + public boolean isWorkOffline() { + return workOffline; + } + + public void setWorkOffline(boolean workOffline) { + this.workOffline = workOffline; + } + + public boolean isRecursive() { + return isRecursive; + } + + public void setRecursive(boolean recursive) { + isRecursive = recursive; + } + + @Nullable + public File getMavenHome() { + return mavenHome; + } + + public void setMavenHome(@Nullable File mavenHome) { + this.mavenHome = mavenHome; + } + + @Nullable + public File getUserSettingsFile() { + return userSettingsFile; + } + + public void setUserSettingsFile(@Nullable File userSettingsFile) { + this.userSettingsFile = userSettingsFile; + } + + @Nullable + public File getGlobalSettingsFile() { + return globalSettingsFile; + } + + public void setGlobalSettingsFile(@Nullable File globalSettingsFile) { + this.globalSettingsFile = globalSettingsFile; + } + + @Nullable + public File getLocalRepository() { + return localRepository; + } + + public void setLocalRepository(@Nullable File localRepository) { + this.localRepository = localRepository; + } + + public boolean isUsePluginRegistry() { + return usePluginRegistry; + } + + public void setUsePluginRegistry(boolean usePluginRegistry) { + this.usePluginRegistry = usePluginRegistry; + } + + @NotNull + public UpdatePolicy getPluginUpdatePolicy() { + return pluginUpdatePolicy; + } + + public void setPluginUpdatePolicy(@Nullable UpdatePolicy value) { + this.pluginUpdatePolicy = value; + } + + @NotNull + public UpdatePolicy getSnapshotUpdatePolicy() { + return snapshotUpdatePolicy; + } + + public void setSnapshotUpdatePolicy(@Nullable UpdatePolicy value) { + this.snapshotUpdatePolicy = value; + } + + @Nullable + public Properties getProperties() { + return myProperties; + } + + public void setProperties(@Nullable Properties properties) { + myProperties = properties; + } + + @Nullable + public Logger getLogger() { + return myLogger; + } + + public void setLogger(@Nullable final Logger logger) { + myLogger = logger; + } + + + public void setConfigurator(@Nullable final PlexusComponentConfigurator configurator) { + myConfigurator = configurator; + } + + @Nullable + public PlexusComponentConfigurator getConfigurator() { + return myConfigurator; + } +} diff --git a/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/MavenExecutionResult.java b/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/MavenExecutionResult.java new file mode 100644 index 000000000000..bef95fd1369d --- /dev/null +++ b/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/MavenExecutionResult.java @@ -0,0 +1,44 @@ +/* + * Copyright 2000-2009 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.maven.embedder; + +import org.apache.maven.project.MavenProject; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class MavenExecutionResult { + private final MavenProject myMavenProject; + private final List myExceptions; + + public MavenExecutionResult(@Nullable MavenProject mavenProject, List exceptions) { + myMavenProject = mavenProject; + myExceptions = exceptions; + } + + @Nullable + public MavenProject getMavenProject() { + return myMavenProject; + } + + public List getExceptions() { + return myExceptions; + } + + public boolean hasExceptions() { + return !myExceptions.isEmpty(); + } +} diff --git a/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/NullMavenLogger.java b/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/NullMavenLogger.java new file mode 100644 index 000000000000..17aea9782d5f --- /dev/null +++ b/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/NullMavenLogger.java @@ -0,0 +1,12 @@ +package org.jetbrains.maven.embedder; + +/** + * @author Sergey.Anchipolevsky + * Date: 28.01.2010 + */ +class NullMavenLogger extends AbstractMavenLogger { + @Override + protected void printMessage(final int level, final String message, final Throwable throwable) { + // do nothing + } +} diff --git a/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/PlexusComponentConfigurator.java b/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/PlexusComponentConfigurator.java new file mode 100644 index 000000000000..3dc69e083c5a --- /dev/null +++ b/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/PlexusComponentConfigurator.java @@ -0,0 +1,13 @@ +package org.jetbrains.maven.embedder; + +import org.codehaus.plexus.PlexusContainer; +import org.jetbrains.annotations.NotNull; + +/** + * @author Sergey.Anchipolevsky + * Date: 21.09.2009 + */ +public interface PlexusComponentConfigurator { + void configureComponents(@NotNull PlexusContainer container); + +} From b596794fb04f3a559ad77ad78eac5e3d59c401cf Mon Sep 17 00:00:00 2001 From: Xavier Fournet Date: Thu, 6 Sep 2012 16:43:04 +0200 Subject: [PATCH 02/15] [IDEA-91145] Add a new MavenEmbedderWrapper#execute method that permit to specify the project list and explicit profile exclusions --- .../maven/server/MavenServerEmbedder.java | 7 ++++-- .../embedder/Maven2ServerEmbedderImpl.java | 14 +++++++---- .../maven/embedder/MavenEmbedder.java | 23 +++++++++++++++++-- .../server/Maven3ServerEmbedderImpl.java | 9 ++++++-- .../maven/server/MavenEmbedderWrapper.java | 21 ++++++++++++++++- 5 files changed, 63 insertions(+), 11 deletions(-) diff --git a/plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/server/MavenServerEmbedder.java b/plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/server/MavenServerEmbedder.java index c1a2b112727a..37210de9ce84 100644 --- a/plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/server/MavenServerEmbedder.java +++ b/plugins/maven/maven-server-api/src/org/jetbrains/idea/maven/server/MavenServerEmbedder.java @@ -54,8 +54,11 @@ public interface MavenServerEmbedder extends Remote { @NotNull MavenServerExecutionResult execute(@NotNull File file, @NotNull Collection activeProfiles, - @NotNull List goals) throws RemoteException, - MavenServerProcessCanceledException; + @NotNull Collection inactiveProfiles, + @NotNull List goals, + @NotNull final List selectedProjects, + boolean alsoMake, + boolean alsoMakeDependents) throws RemoteException, MavenServerProcessCanceledException; void reset() throws RemoteException; diff --git a/plugins/maven/maven2-server-impl/src/org/jetbrains/idea/maven/server/embedder/Maven2ServerEmbedderImpl.java b/plugins/maven/maven2-server-impl/src/org/jetbrains/idea/maven/server/embedder/Maven2ServerEmbedderImpl.java index 0bee080b8c84..cae29c345b98 100644 --- a/plugins/maven/maven2-server-impl/src/org/jetbrains/idea/maven/server/embedder/Maven2ServerEmbedderImpl.java +++ b/plugins/maven/maven2-server-impl/src/org/jetbrains/idea/maven/server/embedder/Maven2ServerEmbedderImpl.java @@ -327,13 +327,19 @@ public class Maven2ServerEmbedderImpl extends MavenRemoteObject implements Maven } @NotNull + @Override public MavenServerExecutionResult execute(@NotNull final File file, - @NotNull final Collection activeProfiles, - @NotNull final List goals) - throws MavenServerProcessCanceledException, RemoteException { + @NotNull final Collection activeProfiles, + @NotNull final Collection inactiveProfiles, + @NotNull final List goals, + @NotNull final List selectedProjects, + final boolean alsoMake, + final boolean alsoMakeDependents) throws RemoteException, MavenServerProcessCanceledException { return doExecute(new Executor() { public MavenServerExecutionResult execute() throws Exception { - MavenExecutionResult result = myImpl.execute(file, new ArrayList(activeProfiles), goals); + MavenExecutionResult result = myImpl + .execute(file, new ArrayList(activeProfiles), new ArrayList(inactiveProfiles), goals, selectedProjects, alsoMake, + alsoMakeDependents); return createExecutionResult(file, result, null); } }); diff --git a/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/MavenEmbedder.java b/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/MavenEmbedder.java index 3fa0fa4762bd..3926a3d1f030 100644 --- a/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/MavenEmbedder.java +++ b/plugins/maven/maven2-server-impl/src/org/jetbrains/maven/embedder/MavenEmbedder.java @@ -289,9 +289,28 @@ public class MavenEmbedder { @NotNull public MavenExecutionResult execute(@NotNull final File file, @NotNull final List activeProfiles, - @NotNull final List goals) { + @NotNull final List inactiveProfiles, + @NotNull final List goals, + @NotNull final List selectedProjects, + boolean alsoMake, + boolean alsoMakeDependents) { try { - MavenExecutionRequest request = createRequest(file, activeProfiles, Collections.emptyList(), goals); + MavenExecutionRequest request = createRequest(file, activeProfiles, inactiveProfiles, goals); + + if (!selectedProjects.isEmpty()) { + request.setRecursive(true); + request.setSelectedProjects(selectedProjects); + if (alsoMake && alsoMakeDependents) { + request.setMakeBehavior(ReactorManager.MAKE_BOTH_MODE); + } + else if (alsoMake) { + request.setMakeBehavior(ReactorManager.MAKE_MODE); + } + else if (alsoMakeDependents) { + request.setMakeBehavior(ReactorManager.MAKE_DEPENDENTS_MODE); + } + } + Maven maven = getComponent(Maven.class); Method method = maven.getClass().getDeclaredMethod("doExecute", MavenExecutionRequest.class, EventDispatcher.class); method.setAccessible(true); diff --git a/plugins/maven/maven3-server-impl/src/org/jetbrains/idea/maven/server/Maven3ServerEmbedderImpl.java b/plugins/maven/maven3-server-impl/src/org/jetbrains/idea/maven/server/Maven3ServerEmbedderImpl.java index c66c35f7dffd..6bf4947c5de6 100644 --- a/plugins/maven/maven3-server-impl/src/org/jetbrains/idea/maven/server/Maven3ServerEmbedderImpl.java +++ b/plugins/maven/maven3-server-impl/src/org/jetbrains/idea/maven/server/Maven3ServerEmbedderImpl.java @@ -190,8 +190,13 @@ public class Maven3ServerEmbedderImpl extends MavenRemoteObject implements Maven @NotNull @Override - public MavenServerExecutionResult execute(@NotNull File file, @NotNull Collection activeProfiles, @NotNull List goals) - throws RemoteException, MavenServerProcessCanceledException { + public MavenServerExecutionResult execute(@NotNull File file, + @NotNull Collection activeProfiles, + @NotNull Collection inactiveProfiles, + @NotNull List goals, + @NotNull List selectedProjects, + boolean alsoMake, + boolean alsoMakeDependents) throws RemoteException, MavenServerProcessCanceledException { throw new UnsupportedOperationException(); } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/server/MavenEmbedderWrapper.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/server/MavenEmbedderWrapper.java index 520c3d9c4f76..3686d6f7c0e7 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/server/MavenEmbedderWrapper.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/server/MavenEmbedderWrapper.java @@ -157,7 +157,26 @@ public abstract class MavenEmbedderWrapper extends RemoteObjectWrapper() { @Override public MavenServerExecutionResult execute() throws RemoteException, MavenServerProcessCanceledException { - return getOrCreateWrappee().execute(new File(file.getPath()), activeProfiles, goals); + return getOrCreateWrappee() + .execute(new File(file.getPath()), activeProfiles, Collections.emptyList(), goals, Collections.emptyList(), false, + false); + } + }); + } + + @NotNull + public MavenServerExecutionResult execute(@NotNull final VirtualFile file, + @NotNull final Collection activeProfiles, + @NotNull final Collection inactiveProfiles, + @NotNull final List goals, + @NotNull final List selectedProjects, + final boolean alsoMake, + final boolean alsoMakeDependents) throws MavenProcessCanceledException { + return perform(new RetriableCancelable() { + @Override + public MavenServerExecutionResult execute() throws RemoteException, MavenServerProcessCanceledException { + return getOrCreateWrappee() + .execute(new File(file.getPath()), activeProfiles, inactiveProfiles, goals, selectedProjects, alsoMake, alsoMakeDependents); } }); } From d88d26418edb5bca31ad4c5caa5d9274f7fac10d Mon Sep 17 00:00:00 2001 From: Xavier Fournet Date: Thu, 6 Sep 2012 16:47:43 +0200 Subject: [PATCH 03/15] [IDEA-91145] Add methods to find Maven root projects --- .../idea/maven/project/MavenProjectsTree.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsTree.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsTree.java index 1c92e44d2432..a6d1d74eb6af 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsTree.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenProjectsTree.java @@ -918,6 +918,33 @@ public class MavenProjectsTree { } } + public MavenProject findRootProject(@NotNull MavenProject project) { + readLock(); + try { + MavenProject rootProject = project; + while (true) { + MavenProject aggregator = myModuleToAggregatorMapping.get(project); + if (aggregator == null) { + return rootProject; + } + rootProject = aggregator; + } + } + finally { + readUnlock(); + } + } + + public boolean isRootProject(@NotNull MavenProject project) { + readLock(); + try { + return myModuleToAggregatorMapping.get(project) == null; + } + finally { + readUnlock(); + } + } + public List getModules(MavenProject aggregator) { readLock(); try { From de18d5bf86be15b00fa2bbf018f0d858e233451c Mon Sep 17 00:00:00 2001 From: Evgeny Zakrevsky Date: Tue, 23 Oct 2012 16:15:45 +0400 Subject: [PATCH 04/15] Tasks. Generic Web Connector. GET and POST types of requests. --- .../tasks/generic/GenericWebRepository.java | 95 +++++++++++++++---- .../generic/GenericWebRepositoryEditor.java | 80 +++++++++++----- .../generic/GenericWebRepositoryType.java | 2 +- plugins/tasks/tasks-core/tasks-core.iml | 2 + 4 files changed, 132 insertions(+), 47 deletions(-) diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericWebRepository.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericWebRepository.java index 5667f41a08e7..989ac869e27d 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericWebRepository.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericWebRepository.java @@ -9,7 +9,9 @@ import com.intellij.tasks.impl.BaseRepositoryImpl; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.xmlb.annotations.Tag; import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.methods.GetMethod; +import org.apache.commons.httpclient.methods.PostMethod; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; @@ -26,6 +28,8 @@ public class GenericWebRepository extends BaseRepositoryImpl { private String myTasksListURL = ""; private String myTaskPattern = ""; private String myLoginURL = ""; + private String myLoginMethodType = GenericWebRepositoryEditor.GET; + private String myGetTasksMethodType = GenericWebRepositoryEditor.GET; final static String SERVER_URL_PLACEHOLDER = "{serverUrl}"; final static String USERNAME_PLACEHOLDER = "{username}"; @@ -33,7 +37,10 @@ public class GenericWebRepository extends BaseRepositoryImpl { final static String ID_PLACEHOLDER = "{id}"; final static String SUMMARY_PLACEHOLDER = "{summary}"; final static String QUERY_PLACEHOLDER = "{query}"; + final static String MAX_COUNT_PLACEHOLDER = "{count}"; + //todo final static String DESCRIPTION_PLACEHOLDER = "{description}"; + //todo final static String PAGE_PLACEHOLDER = "{page}"; @SuppressWarnings({"UnusedDeclaration"}) @@ -49,6 +56,8 @@ public class GenericWebRepository extends BaseRepositoryImpl { myTasksListURL = other.getTasksListURL(); myTaskPattern = other.getTaskPattern(); myLoginURL = other.getLoginURL(); + myLoginMethodType = other.getLoginMethodType(); + myGetTasksMethodType = other.getGetTasksMethodType(); } @Override @@ -57,10 +66,16 @@ public class GenericWebRepository extends BaseRepositoryImpl { if (!isLoginAnonymously()) login(httpClient); - final GetMethod getMethod = new GetMethod(getFullTasksUrl(query != null ? query : "")); - httpClient.executeMethod(getMethod); - if (getMethod.getStatusCode() != 200) throw new Exception("Cannot get tasks: HTTP status code " + getMethod.getStatusCode()); - final String response = getMethod.getResponseBodyAsString(Integer.MAX_VALUE); + final List placeholders = getPlaceholders(myTaskPattern); + if (!placeholders.contains(ID_PLACEHOLDER) || !placeholders.contains(SUMMARY_PLACEHOLDER)) { + throw new Exception("Incorrect Task Pattern"); + } + + //todo add possibility to select method type + final HttpMethod method = getTaskListsMethod(query != null ? query : "", max); + httpClient.executeMethod(method); + if (method.getStatusCode() != 200) throw new Exception("Cannot get tasks: HTTP status code " + method.getStatusCode()); + final String response = method.getResponseBodyAsString(); final String taskPatternWithoutPlaceholders = myTaskPattern.replaceAll("\\{.+?\\}", ""); Matcher matcher = Pattern @@ -68,11 +83,6 @@ public class GenericWebRepository extends BaseRepositoryImpl { Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL | Pattern.UNICODE_CASE | Pattern.CANON_EQ) .matcher(response); - final List placeholders = getPlaceholders(myTaskPattern); - if (matcher.groupCount() != 2 || !placeholders.contains(ID_PLACEHOLDER) || !placeholders.contains(SUMMARY_PLACEHOLDER)) { - throw new Exception("Incorrect Task Pattern"); - } - List tasks = new ArrayList(); while (matcher.find()) { final String id = matcher.group(placeholders.indexOf(ID_PLACEHOLDER) + 1); @@ -86,12 +96,42 @@ public class GenericWebRepository extends BaseRepositoryImpl { return tasks.toArray(new Task[tasks.size()]); } + private HttpMethod getTaskListsMethod(final String query, final int max) { + String requestUrl = getFullTasksUrl(query, max); + return GenericWebRepositoryEditor.GET.equals(myGetTasksMethodType) ? new GetMethod(requestUrl) : getPostMethodFromURL(requestUrl); + } + private void login(final HttpClient httpClient) throws Exception { - final GetMethod method = new GetMethod(getFullLoginUrl()); + final HttpMethod method = getLoginMethod(); httpClient.executeMethod(method); if (method.getStatusCode() != 200) throw new Exception("Cannot login: HTTP status code " + method.getStatusCode()); } + private HttpMethod getLoginMethod() { + String requestUrl = getFullLoginUrl(); + return GenericWebRepositoryEditor.GET.equals(myLoginMethodType) ? new GetMethod(requestUrl) : getPostMethodFromURL(requestUrl); + } + + private static HttpMethod getPostMethodFromURL(final String requestUrl) { + int n = requestUrl.indexOf('?'); + if (n == -1) { + return new PostMethod(requestUrl); + } + + PostMethod postMethod = new PostMethod(requestUrl.substring(0, n)); + n = requestUrl.indexOf('?'); + String[] requestParams = requestUrl.substring(n + 1).split("&"); + for (String requestParam : requestParams) { + String[] nv = requestParam.split("="); + if (nv.length == 1) { + postMethod.addParameter(nv[0], ""); + } else { + postMethod.addParameter(nv[0], nv[1]); + } + } + return postMethod; + } + private static List getPlaceholders(String value) { if (value == null) { return ContainerUtil.emptyList(); @@ -105,21 +145,18 @@ public class GenericWebRepository extends BaseRepositoryImpl { return vars; } - private String getFullTasksUrl(final String query) { + private String getFullTasksUrl(final String query, final int max) { return getTasksListURL() - .replaceAll(placeholder2regexp(SERVER_URL_PLACEHOLDER), getUrl()) - .replaceAll(placeholder2regexp(QUERY_PLACEHOLDER), query); + .replaceAll(Pattern.quote(SERVER_URL_PLACEHOLDER), getUrl()) + .replaceAll(Pattern.quote(QUERY_PLACEHOLDER), encodeUrl(query)) + .replaceAll(Pattern.quote(MAX_COUNT_PLACEHOLDER), String.valueOf(max)); } private String getFullLoginUrl() { return getLoginURL() - .replaceAll(placeholder2regexp(SERVER_URL_PLACEHOLDER), getUrl()) - .replaceAll(placeholder2regexp(USERNAME_PLACEHOLDER), getUsername()) - .replaceAll(placeholder2regexp(PASSWORD_PLACEHOLDER), getPassword()); - } - - private static String placeholder2regexp(String placeholder) { - return placeholder.replaceAll("\\{", "\\\\{"); + .replaceAll(Pattern.quote(SERVER_URL_PLACEHOLDER), getUrl()) + .replaceAll(Pattern.quote(USERNAME_PLACEHOLDER), encodeUrl(getUsername())) + .replaceAll(Pattern.quote(PASSWORD_PLACEHOLDER), encodeUrl(getPassword())); } @Nullable @@ -158,6 +195,8 @@ public class GenericWebRepository extends BaseRepositoryImpl { if (!Comparing.equal(getTasksListURL(), that.getTasksListURL())) return false; if (!Comparing.equal(getTaskPattern(), that.getTaskPattern())) return false; if (!Comparing.equal(getLoginURL(), that.getLoginURL())) return false; + if (!Comparing.equal(getLoginMethodType(), that.getLoginMethodType())) return false; + if (!Comparing.equal(getGetTasksMethodType(), that.getGetTasksMethodType())) return false; return true; } @@ -184,4 +223,20 @@ public class GenericWebRepository extends BaseRepositoryImpl { public void setLoginURL(final String loginURL) { myLoginURL = loginURL; } + + public void setLoginMethodType(final String loginMethodType) { + myLoginMethodType = loginMethodType; + } + + public void setGetTasksMethodType(final String getTasksMethodType) { + myGetTasksMethodType = getTasksMethodType; + } + + public String getLoginMethodType() { + return myLoginMethodType; + } + + public String getGetTasksMethodType() { + return myGetTasksMethodType; + } } diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericWebRepositoryEditor.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericWebRepositoryEditor.java index 6e476417564f..ab9119779fc3 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericWebRepositoryEditor.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericWebRepositoryEditor.java @@ -1,41 +1,52 @@ package com.intellij.tasks.generic; +import com.intellij.ide.highlighter.HtmlFileType; import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.actionSystem.IdeActions; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.EditorFactory; import com.intellij.openapi.keymap.KeymapUtil; import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.ComboBox; import com.intellij.tasks.config.BaseRepositoryEditor; import com.intellij.ui.TextFieldWithAutoCompletion; +import com.intellij.ui.TextFieldWithAutoCompletionContributor; import com.intellij.ui.components.JBLabel; import com.intellij.util.Consumer; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.ui.FormBuilder; +import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import java.awt.*; +import java.util.ArrayList; import static com.intellij.tasks.generic.GenericWebRepository.*; +import static com.intellij.ui.TextFieldWithAutoCompletion.StringsCompletionProvider; /** * User: Evgeny.Zakrevsky * Date: 10/4/12 */ public class GenericWebRepositoryEditor extends BaseRepositoryEditor { + public static final String POST = "POST"; + public static final String GET = "GET"; private JBLabel myTasksListURLLabel; private JBLabel myTaskPatternLabel; private TextFieldWithAutoCompletion myTasksListURLText; - private TextFieldWithAutoCompletion myTaskPatternText; + private Editor myTaskPatternText; private JBLabel myLoginURLLabel; private TextFieldWithAutoCompletion myLoginURLText; + private ComboBox myLoginMethodType; + private ComboBox myGetTasksMethodType; public GenericWebRepositoryEditor(final Project project, final GenericWebRepository repository, final Consumer changeListener) { super(project, repository, changeListener); - myUrlLabel.setText("{serverUrl}:"); - myUsernameLabel.setText("{username}:"); - myPasswordLabel.setText("{password}:"); + myUrlLabel.setText("Server URL"); } @Override @@ -43,13 +54,16 @@ public class GenericWebRepositoryEditor extends BaseRepositoryEditor completionList1 = ContainerUtil.newArrayList(SERVER_URL_PLACEHOLDER, QUERY_PLACEHOLDER, MAX_COUNT_PLACEHOLDER); + myTasksListURLText = TextFieldWithAutoCompletion.create(myProject, completionList1, null, false, myRepository.getTasksListURL()); installListener(myTasksListURLText.getDocument()); + myGetTasksMethodType = new ComboBox(new String[]{GET, POST}, -1); + myGetTasksMethodType.setSelectedItem(myRepository.getGetTasksMethodType()); + installListener(myGetTasksMethodType); + JPanel tasksPanel = new JPanel(new BorderLayout(UIUtil.DEFAULT_HGAP, UIUtil.DEFAULT_VGAP)); + tasksPanel.add(myTasksListURLText, BorderLayout.CENTER); + tasksPanel.add(myGetTasksMethodType, BorderLayout.EAST); myTaskPatternLabel = new JBLabel("Task Pattern:", SwingConstants.RIGHT); - myTaskPatternText = - TextFieldWithAutoCompletion - .create(myProject, ContainerUtil.newArrayList("({id}.+?)", "({summary}.+?)"), null, false, myRepository.getTaskPattern()); - installListener(myTaskPatternText.getDocument()); + final Document document = EditorFactory.getInstance().createDocument(myRepository.getTaskPattern()); + myTaskPatternText = EditorFactory.getInstance().createEditor(document, myProject, HtmlFileType.INSTANCE, false); + final ArrayList completionList2 = ContainerUtil.newArrayList("({id}.+?)", "({summary}.+?)"); + TextFieldWithAutoCompletionContributor + .installCompletion(document, myProject, new StringsCompletionProvider(completionList2, null), true); + installListener(document); + myTaskPatternText.getSettings().setLineMarkerAreaShown(false); + myTaskPatternText.getSettings().setFoldingOutlineShown(false); + //todo correct resizing + //todo completion + //todo completion without whitespace before cursor String useCompletionText = ". Use " + KeymapUtil @@ -79,25 +112,20 @@ public class GenericWebRepositoryEditor extends BaseRepositoryEditorAvailable placeholders: " + SERVER_URL_PLACEHOLDER + ", " + USERNAME_PLACEHOLDER + ", " + PASSWORD_PLACEHOLDER + + useCompletionText + "") + .addLabeledComponent(myTasksListURLLabel, tasksPanel) + .addTooltip( + "Available placeholders: " + SERVER_URL_PLACEHOLDER + ", " + MAX_COUNT_PLACEHOLDER + ", " + QUERY_PLACEHOLDER + + " (use for faster tasks search)" + useCompletionText + "") + .addLabeledComponent(myTaskPatternLabel, myTaskPatternText.getComponent()) + .addTooltip( + "Task pattern should be a regexp with two matching groups: ({id}.+?) and ({summary}.+?)" + useCompletionText + "") .getPanel(); } - @Override - public void dispose() { - super.dispose(); - if (myTasksListURLText != null && myTasksListURLText.getEditor() != null) - EditorFactory.getInstance().releaseEditor(myTasksListURLText.getEditor()); - if (myLoginURLText.getEditor() != null) EditorFactory.getInstance().releaseEditor(myLoginURLText.getEditor()); - if (myTaskPatternText.getEditor() != null) EditorFactory.getInstance().releaseEditor(myTaskPatternText.getEditor()); - } - @Override public void setAnchor(@Nullable final JComponent anchor) { super.setAnchor(anchor); diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericWebRepositoryType.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericWebRepositoryType.java index 4317bd459e4e..20ad197ab8f8 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericWebRepositoryType.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/generic/GenericWebRepositoryType.java @@ -18,7 +18,7 @@ public class GenericWebRepositoryType extends BaseRepositoryType + + From 1164ba10d7b6a9f35f43586b175958390c289328 Mon Sep 17 00:00:00 2001 From: Evgeny Zakrevsky Date: Tue, 23 Oct 2012 16:16:09 +0400 Subject: [PATCH 05/15] Tasks. Minor fixes. --- .../src/com/intellij/tasks/mantis/MantisRepositoryEditor.java | 4 ++-- .../src/com/intellij/tasks/youtrack/YouTrackRepository.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/tasks/tasks-core/src/com/intellij/tasks/mantis/MantisRepositoryEditor.java b/plugins/tasks/tasks-core/src/com/intellij/tasks/mantis/MantisRepositoryEditor.java index 3871c1f3d7ac..c1f4819cc8ff 100644 --- a/plugins/tasks/tasks-core/src/com/intellij/tasks/mantis/MantisRepositoryEditor.java +++ b/plugins/tasks/tasks-core/src/com/intellij/tasks/mantis/MantisRepositoryEditor.java @@ -80,7 +80,7 @@ public class MantisRepositoryEditor extends BaseRepositoryEditor Date: Tue, 23 Oct 2012 17:00:53 +0400 Subject: [PATCH 06/15] revert IDEA-58285 Menu is shown partially when focus is not on IDE window before clicking to menu by mouse [Minimal Version Control Menu sometimes shows instead of full one] --- .../src/com/intellij/openapi/actionSystem/impl/ActionMenu.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenu.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenu.java index 7788939afcc4..939e65112e77 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenu.java +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionMenu.java @@ -254,7 +254,7 @@ public final class ActionMenu extends JMenu { mayContextBeInvalid = false; } else { - context = DataManager.getInstance().getDataContext(this); + context = DataManager.getInstance().getDataContext(); mayContextBeInvalid = true; } Utils.fillMenu(myGroup.getAction(), this, myMnemonicEnabled, myPresentationFactory, context, myPlace, true, mayContextBeInvalid); From 20c1898411dc105fa2be5ffd2d64a1531dd42b2b Mon Sep 17 00:00:00 2001 From: Yuri Denison Date: Tue, 23 Oct 2012 17:20:54 +0400 Subject: [PATCH 07/15] fixed ruby refactorings helper strings --- .../src/messages/RefactoringBundle.properties | 6 ------ 1 file changed, 6 deletions(-) diff --git a/platform/platform-resources-en/src/messages/RefactoringBundle.properties b/platform/platform-resources-en/src/messages/RefactoringBundle.properties index 3d6a3f547644..822c569937f8 100644 --- a/platform/platform-resources-en/src/messages/RefactoringBundle.properties +++ b/platform/platform-resources-en/src/messages/RefactoringBundle.properties @@ -144,12 +144,6 @@ refactoring.introduce.name.used.error=This name is already used refactoring.introduce.variable.scope.error=Name clashes with existing variable refactoring.introduce.placing.error=Cannot extract {0} variable -refactoring.inlineVariable=Inline Variable refactoring -refactoring.inlineMethod=Inline Method refactoring -refactoring.introduceField=Extract Field refactoring -refactoring.refactoring.introduceParameter=Extract Parameter refactoring -refactoring.introduceConstant=Extract Constant refactoring -refactoring.extractMethod=Extract Method refactoring variable.of.type=Variable of &type: convert.to.instance.method.title=Convert To Instance Method convertToInstanceMethod.method.is.not.static=Cannot perform the refactoring\nMethod {0} is not static. From 814390a6f906cadf7099f3be5622e02aee895206 Mon Sep 17 00:00:00 2001 From: Vassiliy Kudryashov Date: Tue, 23 Oct 2012 17:25:03 +0400 Subject: [PATCH 08/15] Disable "Edit defaults" action when it does actually nothing. --- .../execution/impl/RunConfigurable.java | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurable.java b/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurable.java index 5fea112a390b..0b531f5c0b9f 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurable.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/RunConfigurable.java @@ -76,6 +76,7 @@ class RunConfigurable extends BaseConfigurable { private static final Icon SHARED_ICON = IconLoader.getTransparentIcon(AllIcons.Nodes.Symlink, .6f); private static final Icon NON_SHARED_ICON = EmptyIcon.ICON_16; @NonNls private static final String DIVIDER_PROPORTION = "dividerProportion"; + @NonNls private static final String DEFAULTS = "Defaults"; private volatile boolean isDisposed = false; @@ -210,7 +211,7 @@ class RunConfigurable extends BaseConfigurable { } // add defaults - final DefaultMutableTreeNode defaults = new DefaultMutableTreeNode("Defaults"); + final DefaultMutableTreeNode defaults = new DefaultMutableTreeNode(DEFAULTS); final ConfigurationType[] configurationTypes = RunManagerImpl.getInstanceImpl(myProject).getConfigurationFactories(); for (final ConfigurationType type : configurationTypes) { if (!(type instanceof UnknownConfigurationType)) { @@ -1269,7 +1270,7 @@ class RunConfigurable extends BaseConfigurable { } public void actionPerformed(final AnActionEvent e) { - TreeNode defaults = TreeUtil.findNodeWithObject("Defaults", myTree.getModel(), myRoot); + TreeNode defaults = TreeUtil.findNodeWithObject(DEFAULTS, myTree.getModel(), myRoot); if (defaults != null) { final ConfigurationType configurationType = getSelectedConfigurationType(); if (configurationType != null) { @@ -1285,7 +1286,19 @@ class RunConfigurable extends BaseConfigurable { @Override public void update(AnActionEvent e) { - e.getPresentation().setEnabled(TreeUtil.findNodeWithObject("Defaults", myTree.getModel(), myRoot) != null); + boolean isEnabled = TreeUtil.findNodeWithObject(DEFAULTS, myTree.getModel(), myRoot) != null; + TreePath path = myTree.getSelectionPath(); + if (path != null) { + Object o = path.getLastPathComponent(); + if (o instanceof DefaultMutableTreeNode && ((DefaultMutableTreeNode)o).getUserObject().equals(DEFAULTS)) { + isEnabled = false; + } + o = path.getParentPath().getLastPathComponent(); + if (o instanceof DefaultMutableTreeNode && ((DefaultMutableTreeNode)o).getUserObject().equals(DEFAULTS)) { + isEnabled = false; + } + } + e.getPresentation().setEnabled(isEnabled); } } @Nullable From ef682bad30fa99508d4d70ef03c2fdeb9c99b554 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Tue, 23 Oct 2012 15:37:26 +0200 Subject: [PATCH 09/15] IDEA-80020 (Unnecessary 'this' qualifier inspection should have an option to exclude field assignment) --- .../siyeh/InspectionGadgetsBundle.properties | 9 +- .../ig/style/UnnecessaryThisInspection.java | 90 +++++++++---------- .../UnnecessaryQualifierForThis.html | 6 +- .../UnnecessaryThis.html | 6 +- 4 files changed, 54 insertions(+), 57 deletions(-) diff --git a/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties b/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties index a9ccb62ac478..b3718f55cb5f 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties +++ b/plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties @@ -752,6 +752,7 @@ thread.start.in.construction.display.name=Call to 'Thread.start()' during object non.final.clone.display.name=Non-final 'clone()' in secure context unnecessary.temporary.on.conversion.from.string.display.name=Unnecessary temporary object in conversion from String unnecessary.this.display.name=Unnecessary 'this' qualifier +unnecessary.this.ignore.assignments.option=Ignore field assignments runtime.exec.with.non.constant.string.display.name=Call to 'Runtime.exec()' with non-constant string system.properties.display.name=Access of system properties chained.method.call.display.name=Chained method calls @@ -1389,7 +1390,7 @@ unnecessary.parentheses.remove.quickfix=Remove unnecessary parentheses unnecessary.qualifier.for.this.remove.quickfix=Remove unnecessary qualifier unnecessary.semicolon.remove.quickfix=Remove unnecessary semicolon unnecessary.super.constructor.remove.quickfix=Remove unnecessary 'super()' -unnecessary.this.remove.quickfix=Remove unnecessary 'this.' +unnecessary.this.remove.quickfix=Remove unnecessary 'this' qualifier overly.strong.type.cast.problem.descriptor=Cast to #ref can be weakened to ''{0}'' #loc field.count.inspection.include.constant.fields.in.count.checkbox=Include constant fields in count field.count.inspection.static.final.fields.count.as.constant.checkbox='static final' fields count as constant @@ -1673,7 +1674,7 @@ ignore.iterator.loop.variables=Ignore java.util.Iterator loop variables rename.catch.parameter.to.ignored=Rename 'catch' parameter to 'ignored' unnecessary.super.qualifier.display.name=Unnecessary 'super' qualifier unnecessary.super.qualifier.problem.descriptor=Qualifier #ref is unnecessary in this context #loc -unnecessary.super.qualifier.quickfix=Remove unnecessary 'super.' +unnecessary.super.qualifier.quickfix=Remove unnecessary 'super' qualifier collections.field.access.replaceable.by.method.call.display.name=Collections.EMPTY_* field access replaceable with 'Collections.empty*()' method call collections.field.access.replaceable.by.method.call.problem.descriptor=#ref replaceable with ''Collections.{0}'' #loc collections.field.access.replaceable.by.method.call.quickfix=Replace with ''{0}'' @@ -1696,7 +1697,7 @@ unnecessary.constant.array.creation.expression.problem.descriptor=#ref#ref() from super class ''{0}'' called, when method from class ''{1}'' might have been expected #loc -ambiguous.method.call.quickfix=Qualify method call with 'super.' +ambiguous.method.call.quickfix=Add 'super' qualifier to method call change.modifier.quickfix=Make ''{0}'' the.whole.project=the whole project this.class=this class @@ -1974,7 +1975,7 @@ ambiguous.field.access.display.name=Inherited field accessed while local variabl ambiguous.field.access.hides.local.variable.problem.descriptor=Field #ref from super class ''{0}'' accessed, while local variable access might be expected #loc ambiguous.field.access.hides.parameter.problem.descriptor=Field #ref from super class ''{0}'' accessed, while parameter access might be expected #loc ambiguous.field.access.hides.field.problem.descriptor=Field #ref from super class ''{0}'' accessed, while field access from surrounding class might be expected #loc -ambiguous.field.access.quickfix=Qualify field access with 'super.' +ambiguous.field.access.quickfix=Add 'super' qualifier to field access string.builder.replaceable.by.string.quickfix=Replace 'StringBuilder' with 'String' string.buffer.replaceable.by.string.quickfix=Replace 'StringBuffer' with 'String' add.0.to.ignore.if.annotated.by.list.quickfix=Add ''{0}'' to ''Ignore if annotated by'' list diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnnecessaryThisInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnnecessaryThisInspection.java index 27af75f92597..cfdd50433dfd 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnnecessaryThisInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/style/UnnecessaryThisInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2012 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,9 +16,11 @@ package com.siyeh.ig.style; import com.intellij.codeInspection.ProblemDescriptor; +import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel; import com.intellij.openapi.project.Project; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; import com.intellij.util.IncorrectOperationException; import com.siyeh.InspectionGadgetsBundle; import com.siyeh.ig.BaseInspection; @@ -27,9 +29,15 @@ import com.siyeh.ig.InspectionGadgetsFix; import com.siyeh.ig.psiutils.ClassUtils; import com.siyeh.ig.psiutils.VariableSearchUtils; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; public class UnnecessaryThisInspection extends BaseInspection { + @SuppressWarnings("PublicField") + public boolean ignoreAssignments = false; + @Override @NotNull public String getDisplayName() { @@ -39,8 +47,14 @@ public class UnnecessaryThisInspection extends BaseInspection { @Override @NotNull protected String buildErrorString(Object... infos) { - return InspectionGadgetsBundle.message( - "unnecessary.this.problem.descriptor"); + return InspectionGadgetsBundle.message("unnecessary.this.problem.descriptor"); + } + + @Nullable + @Override + public JComponent createOptionsPanel() { + return new SingleCheckboxOptionsPanel(InspectionGadgetsBundle.message("unnecessary.this.ignore.assignments.option"), this, + "ignoreAssignments"); } @Override @@ -52,8 +66,7 @@ public class UnnecessaryThisInspection extends BaseInspection { @NotNull public String getName() { - return InspectionGadgetsBundle.message( - "unnecessary.this.remove.quickfix"); + return InspectionGadgetsBundle.message("unnecessary.this.remove.quickfix"); } public void doFix(Project project, ProblemDescriptor descriptor) @@ -75,33 +88,31 @@ public class UnnecessaryThisInspection extends BaseInspection { return new UnnecessaryThisVisitor(); } - private static class UnnecessaryThisVisitor extends BaseInspectionVisitor { + private class UnnecessaryThisVisitor extends BaseInspectionVisitor { @Override - public void visitReferenceExpression( - @NotNull PsiReferenceExpression expression) { + public void visitReferenceExpression(@NotNull PsiReferenceExpression expression) { super.visitReferenceExpression(expression); - final PsiReferenceParameterList parameterList = - expression.getParameterList(); + final PsiReferenceParameterList parameterList = expression.getParameterList(); if (parameterList == null) { return; } if (parameterList.getTypeArguments().length > 0) { return; } - final PsiExpression qualifierExpression = - expression.getQualifierExpression(); + final PsiExpression qualifierExpression = expression.getQualifierExpression(); if (!(qualifierExpression instanceof PsiThisExpression)) { return; } - final PsiThisExpression thisExpression = - (PsiThisExpression)qualifierExpression; - final PsiJavaCodeReferenceElement qualifier = - thisExpression.getQualifier(); + final PsiThisExpression thisExpression = (PsiThisExpression)qualifierExpression; + final PsiJavaCodeReferenceElement qualifier = thisExpression.getQualifier(); final String referenceName = expression.getReferenceName(); if (referenceName == null) { return; } + if (ignoreAssignments && PsiUtil.isAccessedForWriting(expression)) { + return; + } final PsiElement parent = expression.getParent(); if (qualifier == null) { if (parent instanceof PsiCallExpression) { @@ -114,8 +125,7 @@ public class UnnecessaryThisInspection extends BaseInspection { return; } final PsiVariable variable = (PsiVariable)target; - if (!VariableSearchUtils.variableNameResolvesToTarget( - referenceName, variable, expression)) { + if (!VariableSearchUtils.variableNameResolvesToTarget(referenceName, variable, expression)) { return; } registerError(thisExpression); @@ -126,43 +136,31 @@ public class UnnecessaryThisInspection extends BaseInspection { return; } if (parent instanceof PsiCallExpression) { - final PsiCallExpression callExpression = - (PsiCallExpression)parent; - final PsiMethod calledMethod = - callExpression.resolveMethod(); + final PsiCallExpression callExpression = (PsiCallExpression)parent; + final PsiMethod calledMethod = callExpression.resolveMethod(); if (calledMethod == null) { return; } final String methodName = calledMethod.getName(); - PsiClass parentClass = - ClassUtils.getContainingClass(expression); + PsiClass parentClass = ClassUtils.getContainingClass(expression); final Project project = expression.getProject(); - final JavaPsiFacade psiFacade = - JavaPsiFacade.getInstance(project); - final PsiResolveHelper resolveHelper = - psiFacade.getResolveHelper(); + final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project); + final PsiResolveHelper resolveHelper = psiFacade.getResolveHelper(); while (parentClass != null) { if (qualifierName.equals(parentClass.getName())) { registerError(thisExpression); } - final PsiMethod[] methods = - parentClass.findMethodsByName(methodName, true); + final PsiMethod[] methods = parentClass.findMethodsByName(methodName, true); for (PsiMethod method : methods) { - final PsiClass containingClass = - method.getContainingClass(); - if (resolveHelper.isAccessible(method, - expression, containingClass)) { - if (method.hasModifierProperty( - PsiModifier.PRIVATE) && - !PsiTreeUtil.isAncestor(containingClass, - expression, true)) { + final PsiClass containingClass = method.getContainingClass(); + if (resolveHelper.isAccessible(method, expression, containingClass)) { + if (method.hasModifierProperty(PsiModifier.PRIVATE) && !PsiTreeUtil.isAncestor(containingClass, expression, true)) { continue; } return; } } - parentClass = - ClassUtils.getContainingClass(parentClass); + parentClass = ClassUtils.getContainingClass(parentClass); } } else { @@ -171,23 +169,19 @@ public class UnnecessaryThisInspection extends BaseInspection { return; } final PsiVariable variable = (PsiVariable)target; - if (!VariableSearchUtils.variableNameResolvesToTarget( - referenceName, variable, expression)) { + if (!VariableSearchUtils.variableNameResolvesToTarget(referenceName, variable, expression)) { return; } - PsiClass parentClass = - ClassUtils.getContainingClass(expression); + PsiClass parentClass = ClassUtils.getContainingClass(expression); while (parentClass != null) { if (qualifierName.equals(parentClass.getName())) { registerError(thisExpression); } - final PsiField field = - parentClass.findFieldByName(referenceName, true); + final PsiField field = parentClass.findFieldByName(referenceName, true); if (field != null) { return; } - parentClass = - ClassUtils.getContainingClass(parentClass); + parentClass = ClassUtils.getContainingClass(parentClass); } } } diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryQualifierForThis.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryQualifierForThis.html index fa42638c0f10..6500530e820b 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryQualifierForThis.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryQualifierForThis.html @@ -1,11 +1,11 @@ -Reports on any unnecessary qualification of this in the code. +Reports on any unnecessary qualification of this. Using a qualifier on this to disambiguate a code reference may easily become unnecessary via automatic refactorings, and should be deleted for clarity.

-Sample: -OuterClass.this.foo(); +For example: +

OuterClass.this.foo();

Powered by InspectionGadgets diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryThis.html b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryThis.html index 43c4cabafdc1..d2b583cc7172 100644 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryThis.html +++ b/plugins/InspectionGadgets/src/inspectionDescriptions/UnnecessaryThis.html @@ -5,10 +5,12 @@ Using this to disambiguate a code reference may easily become unnecessary via automatic refactorings, and is discouraged by many coding styles.

-Sample: -this.a=3; +For example: +

this.a = 3;

+Use the checkbox below to ignore assignments to fields. +

Powered by InspectionGadgets \ No newline at end of file From f31fb5f5f3516cecad5a248e4cc9c78a0c14ab06 Mon Sep 17 00:00:00 2001 From: "Denis.Zhdanov" Date: Tue, 23 Oct 2012 17:38:51 +0400 Subject: [PATCH 10/15] IDEA-75133 Provide an action to reset font zoom to default --- .../editor/actions/ResetFontSizeAction.java | 50 +++++++++++++++++++ .../src/messages/ActionsBundle.properties | 1 + .../src/idea/PlatformActions.xml | 1 + 3 files changed, 52 insertions(+) create mode 100644 platform/platform-impl/src/com/intellij/openapi/editor/actions/ResetFontSizeAction.java diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/ResetFontSizeAction.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/ResetFontSizeAction.java new file mode 100644 index 000000000000..62548b9c19fb --- /dev/null +++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/ResetFontSizeAction.java @@ -0,0 +1,50 @@ +/* + * Copyright 2000-2012 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 com.intellij.openapi.editor.actions; + +import com.intellij.execution.impl.ConsoleViewUtil; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; +import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.editor.ex.EditorEx; + +/** + * @author Denis Zhdanov + * @since 10/23/12 4:52 PM + */ +public class ResetFontSizeAction extends EditorAction { + + public ResetFontSizeAction() { + super(new MyHandler()); + } + + private static class MyHandler extends EditorActionHandler { + @Override + public void execute(Editor editor, DataContext dataContext) { + if (!(editor instanceof EditorEx)) { + return; + } + EditorColorsScheme globalScheme = EditorColorsManager.getInstance().getGlobalScheme(); + int fontSize = editor.getUserData(ConsoleViewUtil.EDITOR_IS_CONSOLE_VIEW) == Boolean.TRUE + ? globalScheme.getConsoleFontSize() : globalScheme.getEditorFontSize(); + EditorEx editorEx = (EditorEx)editor; + editorEx.setFontSize(fontSize); + } + } +} diff --git a/platform/platform-resources-en/src/messages/ActionsBundle.properties b/platform/platform-resources-en/src/messages/ActionsBundle.properties index 2f0cb90e6e6f..91cca6767251 100644 --- a/platform/platform-resources-en/src/messages/ActionsBundle.properties +++ b/platform/platform-resources-en/src/messages/ActionsBundle.properties @@ -88,6 +88,7 @@ action.EditorRightWithSelection.text=Right with Selection action.EditorIndentSelection.text=Indent Selection action.EditorUnindentSelection.text=Unindent Selection action.EditorTab.text=Tab +action.EditorResetFontSize.text=Reset Font Size action.EmacsStyleIndent.text=Emacs Tab action.EditorScrollUp.text=Scroll Up action.EditorScrollDown.text=Scroll Down diff --git a/platform/platform-resources/src/idea/PlatformActions.xml b/platform/platform-resources/src/idea/PlatformActions.xml index cd0ab21cc347..995dd9afa8e4 100644 --- a/platform/platform-resources/src/idea/PlatformActions.xml +++ b/platform/platform-resources/src/idea/PlatformActions.xml @@ -59,6 +59,7 @@ + From 60d9c2cee421e84a1a62d4912f722db5fdb2fc7d Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Fri, 19 Oct 2012 19:14:19 +0400 Subject: [PATCH 11/15] IDEA-93257 Groovy: good code is red when annotation attribute is named "def" --- .../GrKeywordAndDeclarationHighlighter.java | 2 ++ .../annotations/AnnotationArguments.java | 13 +++++++--- .../GrAnnotationNameValuePairImpl.java | 9 ++++++- .../lang/parser/AnnotationsParsingTest.groovy | 24 +++++++++++++++++ .../lang/parser/AnnotationsParsingTest.java | 26 ------------------- .../groovy/annotations/defAttribute.test | 25 ++++++++++++++++++ 6 files changed, 69 insertions(+), 30 deletions(-) create mode 100644 plugins/groovy/test/org/jetbrains/plugins/groovy/lang/parser/AnnotationsParsingTest.groovy delete mode 100644 plugins/groovy/test/org/jetbrains/plugins/groovy/lang/parser/AnnotationsParsingTest.java create mode 100644 plugins/groovy/testdata/parsing/groovy/annotations/defAttribute.test diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GrKeywordAndDeclarationHighlighter.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GrKeywordAndDeclarationHighlighter.java index 68217b75294e..e27a9077b0d0 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GrKeywordAndDeclarationHighlighter.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GrKeywordAndDeclarationHighlighter.java @@ -36,6 +36,7 @@ import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrLabel; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation; +import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationNameValuePair; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentLabel; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement; @@ -101,6 +102,7 @@ public class GrKeywordAndDeclarationHighlighter extends TextEditorHighlightingPa return false; //It is allowed to name packages 'as', 'in' or 'def' } } + else if (token == GroovyTokenTypes.kDEF && element.getParent() instanceof GrAnnotationNameValuePair) return false; else if (parent instanceof GrReferenceExpression && element == ((GrReferenceExpression)parent).getReferenceNameElement()) { return false; //don't highlight foo.def } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/auxiliary/annotations/AnnotationArguments.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/auxiliary/annotations/AnnotationArguments.java index 4bb0a5a55b2f..c9c3773233e4 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/auxiliary/annotations/AnnotationArguments.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/auxiliary/annotations/AnnotationArguments.java @@ -42,7 +42,7 @@ public class AnnotationArguments implements GroovyElementTypes { return; } - if (ParserUtils.lookAhead(builder, mIDENT, mASSIGN)) { + if (checkIdentAndAssign(builder)) { parsePairs(builder, parser); } else { @@ -60,6 +60,11 @@ public class AnnotationArguments implements GroovyElementTypes { annArgs.done(ANNOTATION_ARGUMENTS); } + private static boolean checkIdentAndAssign(PsiBuilder builder) { + //def is valid name identifier + return ParserUtils.lookAhead(builder, mIDENT, mASSIGN) || ParserUtils.lookAhead(builder, kDEF, mASSIGN); + } + /* * annotationMemberValueInitializer ::= conditionalExpression | annotation */ @@ -114,8 +119,10 @@ public class AnnotationArguments implements GroovyElementTypes { private static boolean parsePair(PsiBuilder builder, GroovyParser parser) { PsiBuilder.Marker marker = builder.mark(); - if (ParserUtils.lookAhead(builder, mIDENT, mASSIGN)) { - ParserUtils.getToken(builder, mIDENT); + if (checkIdentAndAssign(builder)) { + if (!ParserUtils.getToken(builder, mIDENT)) { + ParserUtils.getToken(builder, kDEF); + } ParserUtils.getToken(builder, mASSIGN); ParserUtils.getToken(builder, mNLS); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/annotation/GrAnnotationNameValuePairImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/annotation/GrAnnotationNameValuePairImpl.java index bf084a6baf78..aa402bacbb95 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/annotation/GrAnnotationNameValuePairImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/auxiliary/annotation/GrAnnotationNameValuePairImpl.java @@ -20,6 +20,7 @@ import com.intellij.codeInsight.completion.PrefixMatcher; import com.intellij.lang.ASTNode; import com.intellij.openapi.util.TextRange; import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -63,7 +64,13 @@ public class GrAnnotationNameValuePairImpl extends GroovyPsiElementImpl implemen @Nullable public PsiElement getNameIdentifierGroovy() { - return findChildByType(GroovyTokenTypes.mIDENT); + PsiElement child = getFirstChild(); + if (child == null) return null; + + IElementType type = child.getNode().getElementType(); + if (type == GroovyTokenTypes.mIDENT || type == GroovyTokenTypes.kDEF) return child; + + return null; } public PsiIdentifier getNameIdentifier() { diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/parser/AnnotationsParsingTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/parser/AnnotationsParsingTest.groovy new file mode 100644 index 000000000000..28cf3d6e47db --- /dev/null +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/parser/AnnotationsParsingTest.groovy @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2000-2005 by JetBrains s.r.o. All Rights Reserved. + * Use is subject to license terms. + */ +package org.jetbrains.plugins.groovy.lang.parser + +/** + * @author peter + */ +public class AnnotationsParsingTest extends GroovyParsingTestCase { + final String basePath = super.basePath + "annotations" + + public void testAnn1() { doTest() } + public void testAnn2() { doTest() } + public void testAnn3() { doTest() } + public void testAnn4() { doTest() } + public void testAnn5() { doTest() } + public void testAnn6() { doTest() } + public void testAnn7() { doTest() } + public void testClassLiteral() { doTest() } + public void testImportAnn() { doTest() } + public void testPackageAnn() { doTest() } + public void testDefAttribute() {doTest()} +} \ No newline at end of file diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/parser/AnnotationsParsingTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/parser/AnnotationsParsingTest.java deleted file mode 100644 index 25ab092d485a..000000000000 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/parser/AnnotationsParsingTest.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2000-2005 by JetBrains s.r.o. All Rights Reserved. - * Use is subject to license terms. - */ -package org.jetbrains.plugins.groovy.lang.parser; - -/** - * @author peter - */ -public class AnnotationsParsingTest extends GroovyParsingTestCase { - @Override - protected String getBasePath() { - return super.getBasePath() + "annotations"; - } - - public void testAnn1() throws Throwable { doTest(); } - public void testAnn2() throws Throwable { doTest(); } - public void testAnn3() throws Throwable { doTest(); } - public void testAnn4() throws Throwable { doTest(); } - public void testAnn5() throws Throwable { doTest(); } - public void testAnn6() throws Throwable { doTest(); } - public void testAnn7() throws Throwable { doTest(); } - public void testClassLiteral() throws Throwable { doTest(); } - public void testImportAnn() throws Throwable { doTest(); } - public void testPackageAnn() throws Throwable { doTest(); } -} \ No newline at end of file diff --git a/plugins/groovy/testdata/parsing/groovy/annotations/defAttribute.test b/plugins/groovy/testdata/parsing/groovy/annotations/defAttribute.test new file mode 100644 index 000000000000..4f193cc3b76a --- /dev/null +++ b/plugins/groovy/testdata/parsing/groovy/annotations/defAttribute.test @@ -0,0 +1,25 @@ +@Foo(def = 4) +def a +----- +Groovy script + Variable definitions + Modifiers + Annotation + PsiElement(@)('@') + Reference element + PsiElement(identifier)('Foo') + Annotation arguments + PsiElement(()('(') + Annotation member value pair + PsiElement(def)('def') + PsiWhiteSpace(' ') + PsiElement(=)('=') + PsiWhiteSpace(' ') + Literal + PsiElement(Integer)('4') + PsiElement())(')') + PsiElement(new line)('\n') + PsiElement(def)('def') + PsiWhiteSpace(' ') + Variable + PsiElement(identifier)('a') \ No newline at end of file From cc60e660b68557bae91b3d12c2b769526dba3ce4 Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Mon, 22 Oct 2012 11:53:59 +0400 Subject: [PATCH 12/15] nullable --- .../org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java index 0e0c1815b9b3..4c766a28ceac 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/PsiImplUtil.java @@ -499,7 +499,7 @@ public class PsiImplUtil { } } - public static void setQualifier(GrQualifiedReference ref, T newQualifier) { + public static void setQualifier(@NotNull GrQualifiedReference ref, @Nullable T newQualifier) { final T oldQualifier = ref.getQualifier(); final ASTNode node = ref.getNode(); final PsiElement refNameElement = ref.getReferenceNameElement(); From 48aba342ad506eaec1c9828bdda2148fdb24a7d8 Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Mon, 22 Oct 2012 11:55:46 +0400 Subject: [PATCH 13/15] Qualified this/super references are allowed only in inner/nested/anonymous classes --- .../plugins/groovy/GroovyBundle.properties | 4 +- .../groovy/annotator/GroovyAnnotator.java | 33 ++++---- .../groovy/lang/Groovy16HighlightingTest.java | 75 ------------------- .../Groovy16HighlightingTest.groovy | 65 ++++++++++++++++ .../GroovyHighlightingTest.groovy | 14 +--- .../SuperWithNotEnclosingClass.groovy | 2 +- .../ThisWithWrongQualifier.groovy | 2 +- 7 files changed, 88 insertions(+), 107 deletions(-) delete mode 100644 plugins/groovy/test/org/jetbrains/plugins/groovy/lang/Groovy16HighlightingTest.java create mode 100644 plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/Groovy16HighlightingTest.groovy diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties index 7aee00157951..ea12ceb3ed2d 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties @@ -334,4 +334,6 @@ top.level.class.maynot.have.protected.modifier=Top level class may not have 'pro property.missing=propertyMissing attribute.name.expected=Attribute name expected java.style.for.each.statement.requires.a.type.declaration=Java-style for-each statement requires a type declaration -enums.may.not.have.extends.clause=Enums may not have 'extends' clause \ No newline at end of file +enums.may.not.have.extends.clause=Enums may not have 'extends' clause +super.cannot.be.used.in.static.context='super' cannot be used in static context +qualified.0.is.allowed.only.in.nested.or.inner.classes=Qualified {0} is allowed only in nested/inner classes \ No newline at end of file diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java index a0c9e87c6bbf..c44b855edace 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java @@ -1032,6 +1032,13 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator { @Override public void visitSuperExpression(GrSuperReferenceExpression superExpression) { + final GrReferenceExpression qualifier = superExpression.getQualifier(); + if (qualifier == null) { + final GrMember container = PsiTreeUtil.getParentOfType(superExpression, GrMethod.class, GrClassInitializer.class); + if (container != null && container.hasModifierProperty(STATIC)) { + myHolder.createErrorAnnotation(superExpression, GroovyBundle.message("super.cannot.be.used.in.static.context")); + } + } checkThisOrSuperReferenceExpression(superExpression, myHolder); } @@ -1409,23 +1416,15 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator { return PsiTreeUtil.getParentOfType(statement, GrLoopStatement.class, true, GrClosableBlock.class, GrMember.class, GroovyFile.class); } - private static void checkThisOrSuperReferenceExpression(GrExpression expression, AnnotationHolder holder) { - if (GroovyConfigUtils.getInstance().isVersionAtLeast(expression, GroovyConfigUtils.GROOVY1_8)) return; - - final GrReferenceExpression qualifier = expression instanceof GrThisReferenceExpression - ? ((GrThisReferenceExpression)expression).getQualifier() - : ((GrSuperReferenceExpression)expression).getQualifier(); - if (qualifier == null) { - if (expression instanceof GrSuperReferenceExpression) { //'this' refers to java.lang.Class in static context - final GrMethod method = PsiTreeUtil.getParentOfType(expression, GrMethod.class); - if (method != null && method.hasModifierProperty(STATIC)) { - Annotation annotation = - holder.createInfoAnnotation(expression, GroovyBundle.message("cannot.reference.nonstatic", expression.getText())); - annotation.setTextAttributes(DefaultHighlighter.UNRESOLVED_ACCESS); - } + private static void checkThisOrSuperReferenceExpression(GrThisSuperReferenceExpression expression, AnnotationHolder holder) { + final GrReferenceExpression qualifier = expression.getQualifier(); + if (qualifier != null) { + GrTypeDefinition containingClass = PsiTreeUtil.getParentOfType(expression, GrTypeDefinition.class, true, GroovyFile.class); + if (containingClass == null || containingClass.getContainingClass() == null && !containingClass.isAnonymous()) { + holder.createErrorAnnotation(expression, GroovyBundle.message("qualified.0.is.allowed.only.in.nested.or.inner.classes", expression.getReferenceName())); + return; } - } - else { + final PsiElement resolved = qualifier.resolve(); if (resolved instanceof PsiClass) { if (PsiTreeUtil.isAncestor(resolved, expression, true)) { @@ -1442,7 +1441,7 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator { } } else { - holder.createErrorAnnotation(qualifier, GroovyBundle.message("unknown.class", qualifier.getText())); + holder.createErrorAnnotation(qualifier, GroovyBundle.message("cannot.resolve", qualifier.getText())); } } } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/Groovy16HighlightingTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/Groovy16HighlightingTest.java deleted file mode 100644 index fa40b8c5134a..000000000000 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/Groovy16HighlightingTest.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2000-2009 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; - -import com.intellij.codeInspection.LocalInspectionTool; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.roots.ContentEntry; -import com.intellij.openapi.roots.ModifiableRootModel; -import com.intellij.openapi.roots.OrderRootType; -import com.intellij.openapi.roots.libraries.Library; -import com.intellij.openapi.vfs.JarFileSystem; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.testFramework.LightProjectDescriptor; -import com.intellij.testFramework.fixtures.DefaultLightProjectDescriptor; -import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyAssignabilityCheckInspection; -import org.jetbrains.plugins.groovy.util.TestUtils; - -/** - * @author peter - */ -@SuppressWarnings({"JUnitTestClassNamingConvention"}) -public class Groovy16HighlightingTest extends LightCodeInsightFixtureTestCase { - private static final DefaultLightProjectDescriptor DESCRIPTOR_1_6 = new DefaultLightProjectDescriptor() { - @Override - public void configureModule(Module module, ModifiableRootModel model, ContentEntry contentEntry) { - final Library.ModifiableModel modifiableModel = model.getModuleLibraryTable().createLibrary("GROOVY").getModifiableModel(); - final VirtualFile groovyJar = - JarFileSystem.getInstance().refreshAndFindFileByPath(TestUtils.getMockGroovy1_6LibraryName() + "!/"); - modifiableModel.addRoot(groovyJar, OrderRootType.CLASSES); - modifiableModel.commit(); - } - }; - - @Override - protected String getBasePath() { - return TestUtils.getTestDataPath() + "highlighting/"; - } - - @NotNull - @Override - protected LightProjectDescriptor getProjectDescriptor() { - return DESCRIPTOR_1_6; - } - - private void doTest(LocalInspectionTool... tools) { - myFixture.enableInspections(tools); - myFixture.testHighlighting(true, false, false, getTestName(false) + ".groovy"); - } - - public void testInnerEnum() throws Exception {doTest();} - public void testSuperWithNotEnclosingClass() throws Throwable {doTest();} - public void testThisWithWrongQualifier() throws Throwable {doTest();} - - public void testImplicitEnumCoercion1_6() { - doTest(new GroovyAssignabilityCheckInspection()); - } - - public void testSlashyStrings() {doTest();} - public void testDiamonds() {doTest();} -} \ No newline at end of file diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/Groovy16HighlightingTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/Groovy16HighlightingTest.groovy new file mode 100644 index 000000000000..40abb4b9a486 --- /dev/null +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/Groovy16HighlightingTest.groovy @@ -0,0 +1,65 @@ +/* + * Copyright 2000-2009 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.highlighting +import com.intellij.codeInspection.LocalInspectionTool +import com.intellij.openapi.module.Module +import com.intellij.openapi.roots.ContentEntry +import com.intellij.openapi.roots.ModifiableRootModel +import com.intellij.openapi.roots.OrderRootType +import com.intellij.openapi.roots.libraries.Library +import com.intellij.openapi.vfs.JarFileSystem +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.testFramework.LightProjectDescriptor +import com.intellij.testFramework.fixtures.DefaultLightProjectDescriptor +import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase +import org.jetbrains.annotations.NotNull +import org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyAssignabilityCheckInspection +import org.jetbrains.plugins.groovy.util.TestUtils +/** + * @author peter + */ +@SuppressWarnings(["JUnitTestClassNamingConvention"]) +public class Groovy16HighlightingTest extends LightCodeInsightFixtureTestCase { + @NotNull + final LightProjectDescriptor projectDescriptor = new DefaultLightProjectDescriptor() { + @Override + public void configureModule(Module module, ModifiableRootModel model, ContentEntry contentEntry) { + final Library.ModifiableModel modifiableModel = model.moduleLibraryTable.createLibrary("GROOVY").modifiableModel + final VirtualFile groovyJar = JarFileSystem.instance.refreshAndFindFileByPath("$TestUtils.mockGroovy1_6LibraryName!/") + modifiableModel.addRoot(groovyJar, OrderRootType.CLASSES) + modifiableModel.commit() + } + } + + final String basePath = TestUtils.testDataPath + "highlighting/" + + private void doTest(LocalInspectionTool... tools) { + myFixture.enableInspections(tools) + myFixture.testHighlighting(true, false, false, getTestName(false) + ".groovy") + } + + public void testInnerEnum() { doTest() } + + public void testSuperWithNotEnclosingClass() { doTest() } + + public void testThisWithWrongQualifier() { doTest() } + + public void testImplicitEnumCoercion1_6() { doTest(new GroovyAssignabilityCheckInspection()) } + + public void testSlashyStrings() { doTest() } + + public void testDiamonds() { doTest() } +} \ No newline at end of file diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GroovyHighlightingTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GroovyHighlightingTest.groovy index 90cecfa9decf..93a3fc1801b9 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GroovyHighlightingTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/highlighting/GroovyHighlightingTest.groovy @@ -14,6 +14,7 @@ * limitations under the License. */ package org.jetbrains.plugins.groovy.lang.highlighting + import com.intellij.testFramework.IdeaTestUtil import com.siyeh.ig.junit.JUnitAbstractTestClassNamingConventionInspection import com.siyeh.ig.junit.JUnitTestClassNamingConventionInspection @@ -21,18 +22,7 @@ import org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyAssignabilit import org.jetbrains.plugins.groovy.codeInspection.confusing.GrUnusedIncDecInspection import org.jetbrains.plugins.groovy.codeInspection.untypedUnresolvedAccess.GrUnresolvedAccessInspection import org.jetbrains.plugins.groovy.codeInspection.unusedDef.UnusedDefInspection -//import org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyAssignabilityCheckInspection -//import org.jetbrains.plugins.groovy.codeInspection.assignment.GroovyResultOfAssignmentUsedInspection -//import org.jetbrains.plugins.groovy.codeInspection.bugs.* -//import org.jetbrains.plugins.groovy.codeInspection.confusing.* -//import org.jetbrains.plugins.groovy.codeInspection.control.GroovyTrivialConditionalInspection -//import org.jetbrains.plugins.groovy.codeInspection.control.GroovyTrivialIfInspection -//import org.jetbrains.plugins.groovy.codeInspection.control.GroovyUnnecessaryReturnInspection -//import org.jetbrains.plugins.groovy.codeInspection.metrics.GroovyOverlyLongMethodInspection -//import org.jetbrains.plugins.groovy.codeInspection.noReturnMethod.MissingReturnInspection -//import org.jetbrains.plugins.groovy.codeInspection.untypedUnresolvedAccess.GrUnresolvedAccessInspection -//import org.jetbrains.plugins.groovy.codeInspection.untypedUnresolvedAccess.GroovyUntypedAccessInspection -//import org.jetbrains.plugins.groovy.codeInspection.unusedDef.UnusedDefInspection + /** * @author peter */ diff --git a/plugins/groovy/testdata/highlighting/SuperWithNotEnclosingClass.groovy b/plugins/groovy/testdata/highlighting/SuperWithNotEnclosingClass.groovy index 275f3a1a0f73..7663247ad903 100644 --- a/plugins/groovy/testdata/highlighting/SuperWithNotEnclosingClass.groovy +++ b/plugins/groovy/testdata/highlighting/SuperWithNotEnclosingClass.groovy @@ -1,5 +1,5 @@ class X{ def foo() { - String.super.toString() + String.super.toString() } } \ No newline at end of file diff --git a/plugins/groovy/testdata/highlighting/ThisWithWrongQualifier.groovy b/plugins/groovy/testdata/highlighting/ThisWithWrongQualifier.groovy index a23fafece73a..04e89b5c7d6e 100644 --- a/plugins/groovy/testdata/highlighting/ThisWithWrongQualifier.groovy +++ b/plugins/groovy/testdata/highlighting/ThisWithWrongQualifier.groovy @@ -1,6 +1,6 @@ class X{ def foo(){ X x=new X(); - x.this.foo(); + x.this.foo(); } } \ No newline at end of file From 320dde0c5c01030ecc4fa9c440bbc005513f96a6 Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Tue, 23 Oct 2012 18:09:22 +0400 Subject: [PATCH 14/15] IDEA-93455 this/super references are reference expressions --- .../groovy/actions/ConvertToJavaAction.java | 5 + .../GrKeywordAndDeclarationHighlighter.java | 2 + .../groovy/annotator/GroovyAnnotator.java | 65 +++++----- .../GrReassignedLocalVarsChecker.java | 1 + .../GroovyAssignabilityCheckInspection.java | 2 +- .../bugs/GroovyAccessibilityInspection.java | 6 +- .../codeInspection/bugs/RecursionUtils.java | 16 +-- .../GroovyPointlessBooleanInspection.java | 2 +- .../GrMethodMayBeStaticInspection.java | 17 ++- ...tterCallCanBePropertyAccessInspection.java | 14 +-- ...oovyListGetCanBeKeyedAccessInspection.java | 7 +- ...oovyListSetCanBeKeyedAccessInspection.java | 7 +- ...roovyMapGetCanBeKeyedAccessInspection.java | 7 +- ...roovyMapPutCanBeKeyedAccessInspection.java | 7 +- ...tterCallCanBePropertyAccessInspection.java | 9 +- ...StaticFieldLockedOnInstanceInspection.java | 23 ++-- ...GroovySynchronizationOnThisInspection.java | 5 +- .../codeInspection/utils/BoolUtils.java | 5 +- .../utils/EquivalenceChecker.java | 35 +++--- .../debugger/GroovyCodeFragmentFactory.java | 34 +++-- .../debugger/GroovyEditorTextProvider.java | 4 - .../GroovyConstructorUsagesSearcher.java | 2 +- .../control/DemorgansLawIntention.java | 4 +- .../control/MergeIfAndIntention.java | 4 +- .../SimplifyTernaryOperatorIntention.java | 4 +- .../ConvertGStringToStringIntention.java | 4 +- .../groovy/intentions/utils/BoolUtils.java | 6 +- .../intentions/utils/ParenthesesUtils.java | 17 ++- .../groovy/lang/GrReferenceAdjuster.java | 11 +- .../groovy/lang/GroovyChangeUtilSupport.java | 23 ++-- .../lang/parser/GroovyElementTypes.java | 2 - .../groovy/lang/parser/GroovyPsiCreator.java | 2 - .../constructor/ConstructorBody.java | 4 +- .../arithmetic/PathExpression.java | 53 +++----- .../primary/PrimaryExpression.java | 10 +- .../primary/StringConstructorExpression.java | 12 +- .../groovy/lang/psi/GroovyElementVisitor.java | 12 -- .../lang/psi/GroovyPsiElementFactory.java | 7 +- .../groovy/lang/psi/api/SpreadState.java | 8 +- .../statements/GrConstructorInvocation.java | 4 +- .../GrThisSuperReferenceExpression.java | 9 ++ .../psi/impl/GroovyPsiElementFactoryImpl.java | 5 +- .../GrConstructorInvocationImpl.java | 35 +++--- .../CompleteReferenceExpression.java | 7 +- .../GrReferenceExpressionImpl.java | 42 +++++-- .../expressions/GrReferenceResolveUtil.java | 77 +++++++++++- .../GrSuperReferenceExpressionImpl.java | 1 - .../GrThisReferenceExpressionImpl.java | 1 - .../GrThisSuperReferenceExpressionBase.java | 6 +- .../statements/expressions/TypesUtil.java | 7 +- .../plugins/groovy/lang/psi/util/PsiUtil.java | 119 ++++++++++++++---- .../groovy/lang/resolve/ResolveUtil.java | 2 - .../refactoring/GroovyChangeContextUtil.java | 8 +- .../refactoring/GroovyNameSuggestionUtil.java | 15 ++- .../refactoring/GroovyRefactoringUtil.java | 4 +- .../GrChangeSignatureUsageProcessor.java | 2 +- .../convertToJava/CodeBlockGenerator.java | 4 +- .../convertToJava/ExpressionGenerator.java | 49 +++++--- .../ExtractClosureFromMethodProcessor.java | 4 +- .../inline/GroovyMethodInliner.java | 15 +-- .../introduce/GrIntroduceHandlerBase.java | 2 +- .../parameter/FieldConflictsResolver.java | 4 +- .../GrIntroduceClosureParameterProcessor.java | 3 +- .../GrIntroduceParameterHandler.java | 2 +- .../GrIntroduceParameterProcessor.java | 3 +- .../GroovyIntroduceParameterUtil.java | 3 +- .../java2groovy/OldReferencesResolver.java | 29 +++-- .../parameter => util}/AnySupers.java | 15 ++- .../Groovy16HighlightingTest.groovy | 2 +- .../groovy/lang/resolve/DelegateTest.groovy | 3 +- .../lang/resolve/TypeInferenceTest.groovy | 2 + .../GrIntroduceParameterTest.java | 4 + .../refactoring/rename/RenameTest.groovy | 26 ++++ .../groovy/expressions/path/path10.test | 2 +- .../expressions/super/qualifiedSuper.test | 2 +- .../groovy/expressions/super/super.test | 2 +- .../expressions/this/qualifiedThis.test | 2 +- .../parsing/groovy/expressions/this/this.test | 2 +- .../typedef/constructors/constructor1.test | 2 +- .../typedef/constructors/constructor13.test | 2 +- .../typedef/constructors/constructor14.test | 4 +- .../typedef/constructors/constructor2.test | 2 +- .../typedef/constructors/constructor3.test | 2 +- .../typedef/constructors/constructor4.test | 2 +- .../typedef/constructors/constructor5.test | 2 +- .../typedef/constructors/constructor6.test | 2 +- .../typedef/constructors/constructor8.test | 2 +- .../typedef/constructors/constructor9.test | 2 +- .../interfaces/errors/interfaceerr1.test | 2 +- .../convertGroovyToJava/file/constructor.java | 2 +- .../file/dynamicPropertiesAccess.java | 2 +- .../QualifiedThisSubstitutionAfter.groovy | 2 + .../QualifiedThisSubstitutionBefore.groovy | 1 + .../QualifiedThisSubstitutionMyClass.groovy | 9 ++ 94 files changed, 594 insertions(+), 428 deletions(-) rename plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/{introduce/parameter => util}/AnySupers.java (68%) create mode 100644 plugins/groovy/testdata/refactoring/introduceParameterGroovy/qualifiedThisSubstitution/QualifiedThisSubstitutionAfter.groovy create mode 100644 plugins/groovy/testdata/refactoring/introduceParameterGroovy/qualifiedThisSubstitution/QualifiedThisSubstitutionBefore.groovy create mode 100644 plugins/groovy/testdata/refactoring/introduceParameterGroovy/qualifiedThisSubstitution/QualifiedThisSubstitutionMyClass.groovy diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/ConvertToJavaAction.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/ConvertToJavaAction.java index da3520067bcf..f134fa21b5ef 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/ConvertToJavaAction.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/actions/ConvertToJavaAction.java @@ -36,6 +36,11 @@ public class ConvertToJavaAction extends BaseRefactoringAction { return isEnabledOnElements(new PsiElement[]{element}); } + @Override + protected boolean isEnabledOnDataContext(DataContext dataContext) { + return super.isEnabledOnDataContext(dataContext); + } + @Override protected boolean isAvailableInEditorOnly() { return false; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GrKeywordAndDeclarationHighlighter.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GrKeywordAndDeclarationHighlighter.java index e27a9077b0d0..f96960beb51e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GrKeywordAndDeclarationHighlighter.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GrKeywordAndDeclarationHighlighter.java @@ -104,6 +104,8 @@ public class GrKeywordAndDeclarationHighlighter extends TextEditorHighlightingPa } else if (token == GroovyTokenTypes.kDEF && element.getParent() instanceof GrAnnotationNameValuePair) return false; else if (parent instanceof GrReferenceExpression && element == ((GrReferenceExpression)parent).getReferenceNameElement()) { + if (token == GroovyTokenTypes.kSUPER && ((GrReferenceExpression)parent).getQualifier() == null) return true; + if (token == GroovyTokenTypes.kTHIS && ((GrReferenceExpression)parent).getQualifier() == null) return true; return false; //don't highlight foo.def } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java index c44b855edace..769eb76b0730 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java @@ -288,6 +288,7 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator { @Override public void visitReferenceExpression(final GrReferenceExpression referenceExpression) { checkStringNameIdentifier(referenceExpression); + checkThisOrSuperReferenceExpression(referenceExpression, myHolder); } private void checkStringNameIdentifier(GrReferenceExpression ref) { @@ -955,7 +956,7 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator { final PsiClass clazz = invocation.getDelegatedClass(); if (clazz != null) { //default constructor invocation - PsiType[] argumentTypes = PsiUtil.getArgumentTypes(invocation.getThisOrSuperKeyword(), true); + PsiType[] argumentTypes = PsiUtil.getArgumentTypes(invocation.getInvokedExpression(), true); if (argumentTypes != null && argumentTypes.length > 0) { String message = GroovyBundle.message("cannot.apply.default.constructor", clazz.getName()); myHolder.createWarningAnnotation(argList, message); @@ -1030,23 +1031,6 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator { } } - @Override - public void visitSuperExpression(GrSuperReferenceExpression superExpression) { - final GrReferenceExpression qualifier = superExpression.getQualifier(); - if (qualifier == null) { - final GrMember container = PsiTreeUtil.getParentOfType(superExpression, GrMethod.class, GrClassInitializer.class); - if (container != null && container.hasModifierProperty(STATIC)) { - myHolder.createErrorAnnotation(superExpression, GroovyBundle.message("super.cannot.be.used.in.static.context")); - } - } - checkThisOrSuperReferenceExpression(superExpression, myHolder); - } - - @Override - public void visitThisExpression(GrThisReferenceExpression thisExpression) { - checkThisOrSuperReferenceExpression(thisExpression, myHolder); - } - @Override public void visitLiteralExpression(GrLiteral literal) { final IElementType elementType = literal.getFirstChild().getNode().getElementType(); @@ -1416,32 +1400,43 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator { return PsiTreeUtil.getParentOfType(statement, GrLoopStatement.class, true, GrClosableBlock.class, GrMember.class, GroovyFile.class); } - private static void checkThisOrSuperReferenceExpression(GrThisSuperReferenceExpression expression, AnnotationHolder holder) { - final GrReferenceExpression qualifier = expression.getQualifier(); - if (qualifier != null) { - GrTypeDefinition containingClass = PsiTreeUtil.getParentOfType(expression, GrTypeDefinition.class, true, GroovyFile.class); - if (containingClass == null || containingClass.getContainingClass() == null && !containingClass.isAnonymous()) { - holder.createErrorAnnotation(expression, GroovyBundle.message("qualified.0.is.allowed.only.in.nested.or.inner.classes", expression.getReferenceName())); - return; - } + private static void checkThisOrSuperReferenceExpression(GrReferenceExpression ref, AnnotationHolder holder) { + PsiElement nameElement = ref.getReferenceNameElement(); + if (nameElement == null) return; - final PsiElement resolved = qualifier.resolve(); + IElementType elementType = nameElement.getNode().getElementType(); + if (!(elementType == GroovyTokenTypes.kSUPER || elementType == GroovyTokenTypes.kTHIS)) return; + + final GrExpression qualifier = ref.getQualifier(); + if (qualifier instanceof GrReferenceExpression) { + final PsiElement resolved = ((GrReferenceExpression)qualifier).resolve(); if (resolved instanceof PsiClass) { - if (PsiTreeUtil.isAncestor(resolved, expression, true)) { - if (!PsiUtil.hasEnclosingInstanceInScope((PsiClass)resolved, expression, true)) { - Annotation annotation = - holder.createInfoAnnotation(expression, GroovyBundle.message("cannot.reference.nonstatic", expression.getText())); - annotation.setTextAttributes(DefaultHighlighter.UNRESOLVED_ACCESS); + + GrTypeDefinition containingClass = PsiTreeUtil.getParentOfType(ref, GrTypeDefinition.class, true, GroovyFile.class); + if (containingClass == null || containingClass.getContainingClass() == null && !containingClass.isAnonymous()) { + holder.createErrorAnnotation(ref, GroovyBundle.message("qualified.0.is.allowed.only.in.nested.or.inner.classes", + nameElement.getText())); + return; + } + + if (PsiTreeUtil.isAncestor(resolved, ref, true)) { + if (PsiUtil.hasEnclosingInstanceInScope((PsiClass)resolved, ref, true)) { + holder.createInfoAnnotation(nameElement, null).setTextAttributes(DefaultHighlighter.KEYWORD); } } else { String qname = ((PsiClass)resolved).getQualifiedName(); assert qname != null; - holder.createErrorAnnotation(expression, GroovyBundle.message("is.not.enclosing.class", qname)); + holder.createErrorAnnotation(ref, GroovyBundle.message("is.not.enclosing.class", qname)); } } - else { - holder.createErrorAnnotation(qualifier, GroovyBundle.message("cannot.resolve", qualifier.getText())); + } + else if (qualifier == null) { + if (elementType == GroovyTokenTypes.kSUPER) { + final GrMember container = PsiTreeUtil.getParentOfType(ref, GrMethod.class, GrClassInitializer.class); + if (container != null && container.hasModifierProperty(STATIC)) { + holder.createErrorAnnotation(ref, GroovyBundle.message("super.cannot.be.used.in.static.context")); + } } } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInsight/GrReassignedLocalVarsChecker.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInsight/GrReassignedLocalVarsChecker.java index 739f4b044543..371b7c58c38e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInsight/GrReassignedLocalVarsChecker.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInsight/GrReassignedLocalVarsChecker.java @@ -58,6 +58,7 @@ public class GrReassignedLocalVarsChecker { return null; } + assert resolved != null; return getLeastUpperBoundByVar((GrVariable)resolved); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/assignment/GroovyAssignabilityCheckInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/assignment/GroovyAssignabilityCheckInspection.java index 8abe3a2aa44b..a28992a6ba40 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/assignment/GroovyAssignabilityCheckInspection.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/assignment/GroovyAssignabilityCheckInspection.java @@ -548,7 +548,7 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection { @Override public void visitConstructorInvocation(GrConstructorInvocation invocation) { super.visitConstructorInvocation(invocation); - checkConstructorCall(invocation, invocation.getThisOrSuperKeyword()); + checkConstructorCall(invocation, invocation.getInvokedExpression()); } @Override diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/bugs/GroovyAccessibilityInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/bugs/GroovyAccessibilityInspection.java index 63e3f934aedf..cf497a0df039 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/bugs/GroovyAccessibilityInspection.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/bugs/GroovyAccessibilityInspection.java @@ -209,7 +209,9 @@ public class GroovyAccessibilityInspection extends BaseInspection { @Override public void visitReferenceExpression(GrReferenceExpression ref) { super.visitReferenceExpression(ref); - checkRef(ref); + if (!(ref.getParent() instanceof GrConstructorInvocation)) { //constructor invocation is checked in separate place + checkRef(ref); + } } @Override @@ -229,7 +231,7 @@ public class GroovyAccessibilityInspection extends BaseInspection { refElement = ((GrNewExpression)call).getReferenceElement(); } else if (call instanceof GrConstructorInvocation) { - refElement = ((GrConstructorInvocation)call).getThisOrSuperKeyword(); + refElement = ((GrConstructorInvocation)call).getInvokedExpression(); } if (refElement == null) { refElement = call; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/bugs/RecursionUtils.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/bugs/RecursionUtils.java index fc42963c8b3a..808131f1ac4c 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/bugs/RecursionUtils.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/bugs/RecursionUtils.java @@ -19,6 +19,7 @@ import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiModifier; import com.intellij.psi.tree.IElementType; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.codeInspection.utils.BoolUtils; import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrCondition; @@ -36,6 +37,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrC import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrIndexProperty; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; +import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; @SuppressWarnings({"OverlyComplexClass"}) class RecursionUtils { @@ -45,7 +47,7 @@ class RecursionUtils { } public static boolean statementMayReturnBeforeRecursing( - GrStatement statement, GrMethod method) { + @Nullable GrStatement statement, GrMethod method) { if (statement == null) { return true; } @@ -183,7 +185,7 @@ class RecursionUtils { } private static boolean codeBlockMayReturnBeforeRecursing( - GrCodeBlock block, GrMethod method, boolean endsInImplicitReturn) { + @Nullable GrCodeBlock block, GrMethod method, boolean endsInImplicitReturn) { if (block == null) { return true; } @@ -205,14 +207,12 @@ class RecursionUtils { return recursionVisitor.isRecursive(); } - private static boolean expressionDefinitelyRecurses(GrExpression exp, + private static boolean expressionDefinitelyRecurses(@Nullable GrExpression exp, GrMethod method) { if (exp == null) { return false; } - if (exp instanceof GrLiteral || - exp instanceof GrThisReferenceExpression || - exp instanceof GrSuperReferenceExpression) { + if (exp instanceof GrLiteral) { return false; } if (exp instanceof GrMethodCallExpression) { @@ -399,7 +399,7 @@ class RecursionUtils { method.hasModifierProperty(PsiModifier.PRIVATE)) { return true; } - if (qualifier == null || qualifier instanceof GrThisReferenceExpression) { + if (qualifier == null || qualifier instanceof GrReferenceExpression && PsiUtil.isThisReference(qualifier)) { return true; } } @@ -410,7 +410,7 @@ class RecursionUtils { return callExpressionDefinitelyRecurses(exp, method); } - private static boolean statementDefinitelyRecurses(GrStatement statement, + private static boolean statementDefinitelyRecurses(@Nullable GrStatement statement, GrMethod method) { if (statement == null) { return false; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/GroovyPointlessBooleanInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/GroovyPointlessBooleanInspection.java index 25c41a72ee67..f8f7105637c4 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/GroovyPointlessBooleanInspection.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/confusing/GroovyPointlessBooleanInspection.java @@ -137,7 +137,7 @@ public class GroovyPointlessBooleanInspection extends BaseInspection { return lhs.getText() + negatedComparison + rhs.getText(); } else { final String baseText = exp.getText(); - if (ParenthesesUtils.getPrecendence(exp) > + if (ParenthesesUtils.getPrecedence(exp) > ParenthesesUtils.PREFIX_PRECEDENCE) { return "!(" + baseText + ')'; } else { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/declaration/GrMethodMayBeStaticInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/declaration/GrMethodMayBeStaticInspection.java index 063cba59f6d4..02e9a6755261 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/declaration/GrMethodMayBeStaticInspection.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/declaration/GrMethodMayBeStaticInspection.java @@ -35,12 +35,12 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlo import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisSuperReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement; import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GroovyScriptClass; +import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; import javax.swing.*; @@ -172,8 +172,14 @@ public class GrMethodMayBeStaticInspection extends BaseInspection { @Override public void visitReferenceExpression(GrReferenceExpression referenceExpression) { + if (PsiUtil.isThisOrSuperRef(referenceExpression)) { + if (referenceExpression.getParent() instanceof GrReferenceExpression) return; + registerInstanceRefs(); + return; + } + GrExpression qualifier = referenceExpression.getQualifierExpression(); - if (qualifier == null || qualifier instanceof GrThisSuperReferenceExpression) { + if (qualifier == null || PsiUtil.isThisOrSuperRef(qualifier)) { GroovyResolveResult result = referenceExpression.advancedResolve(); PsiElement element = result.getElement(); if (isPrintOrPrintln(element)) return; //print & println are resolved in all places @@ -190,13 +196,6 @@ public class GrMethodMayBeStaticInspection extends BaseInspection { } } - @Override - public void visitThisSuperReferenceExpression(GrThisSuperReferenceExpression expression) { - if (expression.getParent() instanceof GrReferenceExpression) return; - - registerInstanceRefs(); - } - private void registerInstanceRefs() { if (myIsInClosure > 0) { myHaveNoInstanceRefsInClosure = false; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyGetterCallCanBePropertyAccessInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyGetterCallCanBePropertyAccessInspection.java index 639a2b259d84..4c9818edcfbc 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyGetterCallCanBePropertyAccessInspection.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyGetterCallCanBePropertyAccessInspection.java @@ -21,18 +21,17 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.NonNls; import org.jetbrains.plugins.groovy.codeInspection.BaseInspection; import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor; import org.jetbrains.plugins.groovy.codeInspection.GroovyFix; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrSuperReferenceExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression; +import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; public class GroovyGetterCallCanBePropertyAccessInspection extends BaseInspection { @@ -98,7 +97,7 @@ public class GroovyGetterCallCanBePropertyAccessInspection extends BaseInspectio if (!(methodExpression instanceof GrReferenceExpression)) { return; } - final GrReferenceExpression referenceExpression = (GrReferenceExpression) methodExpression; + final GrReferenceExpression referenceExpression = (GrReferenceExpression)methodExpression; final String name = referenceExpression.getReferenceName(); if (name == null || !name.startsWith(GET_PREFIX)) { return; @@ -112,11 +111,8 @@ public class GroovyGetterCallCanBePropertyAccessInspection extends BaseInspectio return; } final GrExpression qualifier = referenceExpression.getQualifierExpression(); - if (qualifier == null || - qualifier instanceof GrThisReferenceExpression || - qualifier instanceof GrSuperReferenceExpression) { - return; - } + if (qualifier == null) return; + if (PsiUtil.isThisOrSuperRef(qualifier)) return; registerMethodCallError(grMethodCallExpression); } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyListGetCanBeKeyedAccessInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyListGetCanBeKeyedAccessInspection.java index 83a90b6d166c..33e84dfd9537 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyListGetCanBeKeyedAccessInspection.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyListGetCanBeKeyedAccessInspection.java @@ -32,9 +32,8 @@ import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrSuperReferenceExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression; +import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; public class GroovyListGetCanBeKeyedAccessInspection extends BaseInspection { @@ -106,9 +105,7 @@ public class GroovyListGetCanBeKeyedAccessInspection extends BaseInspection { } final GrExpression qualifier = referenceExpression.getQualifierExpression(); - if (qualifier == null || - qualifier instanceof GrThisReferenceExpression || - qualifier instanceof GrSuperReferenceExpression) { + if (qualifier == null || PsiUtil.isThisOrSuperRef(qualifier)) { return; } if (referenceExpression.getDotTokenType() == GroovyTokenTypes.mOPTIONAL_DOT) return; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyListSetCanBeKeyedAccessInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyListSetCanBeKeyedAccessInspection.java index 28622dd0f52d..695c480b7ee3 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyListSetCanBeKeyedAccessInspection.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyListSetCanBeKeyedAccessInspection.java @@ -32,9 +32,8 @@ import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrSuperReferenceExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression; +import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; public class GroovyListSetCanBeKeyedAccessInspection extends BaseInspection { @@ -107,9 +106,7 @@ public class GroovyListSetCanBeKeyedAccessInspection extends BaseInspection { } final GrExpression qualifier = referenceExpression.getQualifierExpression(); - if (qualifier == null || - qualifier instanceof GrThisReferenceExpression || - qualifier instanceof GrSuperReferenceExpression) { + if (qualifier == null || PsiUtil.isThisOrSuperRef(qualifier)) { return; } if (referenceExpression.getDotTokenType() == GroovyTokenTypes.mOPTIONAL_DOT) return; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyMapGetCanBeKeyedAccessInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyMapGetCanBeKeyedAccessInspection.java index 8b5c637914b1..0d7bc5c20b5d 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyMapGetCanBeKeyedAccessInspection.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyMapGetCanBeKeyedAccessInspection.java @@ -32,9 +32,8 @@ import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrSuperReferenceExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression; +import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; public class GroovyMapGetCanBeKeyedAccessInspection extends BaseInspection { @@ -106,9 +105,7 @@ public class GroovyMapGetCanBeKeyedAccessInspection extends BaseInspection { } final GrExpression qualifier = referenceExpression.getQualifierExpression(); - if (qualifier == null || - qualifier instanceof GrThisReferenceExpression || - qualifier instanceof GrSuperReferenceExpression) { + if (qualifier == null || PsiUtil.isThisOrSuperRef(qualifier)) { return; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyMapPutCanBeKeyedAccessInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyMapPutCanBeKeyedAccessInspection.java index 55b3cecaa3e7..55e1daaf6775 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyMapPutCanBeKeyedAccessInspection.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovyMapPutCanBeKeyedAccessInspection.java @@ -32,9 +32,8 @@ import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrSuperReferenceExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression; +import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; public class GroovyMapPutCanBeKeyedAccessInspection extends BaseInspection { private final ReplaceWithPropertyAccessFix fix = new ReplaceWithPropertyAccessFix(); @@ -108,9 +107,7 @@ public class GroovyMapPutCanBeKeyedAccessInspection extends BaseInspection { } final GrExpression qualifier = referenceExpression.getQualifierExpression(); - if (qualifier == null || - qualifier instanceof GrThisReferenceExpression || - qualifier instanceof GrSuperReferenceExpression) { + if (qualifier == null || PsiUtil.isThisOrSuperRef(qualifier)) { return; } if (referenceExpression.getDotTokenType() == GroovyTokenTypes.mOPTIONAL_DOT) return; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovySetterCallCanBePropertyAccessInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovySetterCallCanBePropertyAccessInspection.java index d2fca172ecda..f9a6975fcd1e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovySetterCallCanBePropertyAccessInspection.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/gpath/GroovySetterCallCanBePropertyAccessInspection.java @@ -21,18 +21,17 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.NonNls; import org.jetbrains.plugins.groovy.codeInspection.BaseInspection; import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor; import org.jetbrains.plugins.groovy.codeInspection.GroovyFix; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrSuperReferenceExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression; +import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; public class GroovySetterCallCanBePropertyAccessInspection extends BaseInspection { private final ReplaceWithPropertyAccessFix fix = new ReplaceWithPropertyAccessFix(); @@ -116,9 +115,7 @@ public class GroovySetterCallCanBePropertyAccessInspection extends BaseInspectio return; } final GrExpression qualifier = referenceExpression.getQualifierExpression(); - if (qualifier == null || - qualifier instanceof GrThisReferenceExpression || - qualifier instanceof GrSuperReferenceExpression) { + if (qualifier == null || PsiUtil.isThisOrSuperRef(qualifier)) { return; } registerMethodCallError(grMethodCallExpression); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/threading/GroovyAccessToStaticFieldLockedOnInstanceInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/threading/GroovyAccessToStaticFieldLockedOnInstanceInspection.java index e39a99a645ab..2901bebb50df 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/threading/GroovyAccessToStaticFieldLockedOnInstanceInspection.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/threading/GroovyAccessToStaticFieldLockedOnInstanceInspection.java @@ -27,8 +27,8 @@ import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrSynchronizedStatement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; +import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; public class GroovyAccessToStaticFieldLockedOnInstanceInspection extends BaseInspection { @@ -79,29 +79,26 @@ public class GroovyAccessToStaticFieldLockedOnInstanceInspection } PsiElement elementToCheck = expression; while (true) { - final GrSynchronizedStatement syncStatement = - PsiTreeUtil.getParentOfType(elementToCheck, - GrSynchronizedStatement.class); + final GrSynchronizedStatement syncStatement = PsiTreeUtil.getParentOfType(elementToCheck, GrSynchronizedStatement.class); if (syncStatement == null) { break; } - final GrExpression lockExpression = - syncStatement.getMonitor(); - if (lockExpression instanceof GrReferenceExpression) { - final GrReferenceExpression reference = - (GrReferenceExpression) lockExpression; + final GrExpression lockExpression = syncStatement.getMonitor(); + + if (lockExpression instanceof GrReferenceExpression && PsiUtil.isThisReference(lockExpression)) { + isLockedOnInstance = true; + } + else if (lockExpression instanceof GrReferenceExpression) { + final GrReferenceExpression reference = (GrReferenceExpression) lockExpression; final PsiElement referent = reference.resolve(); if (referent instanceof PsiField) { final PsiField referentField = (PsiField) referent; - if (referentField.hasModifierProperty( - PsiModifier.STATIC)) { + if (referentField.hasModifierProperty(PsiModifier.STATIC)) { isLockedOnClass = true; } else { isLockedOnInstance = true; } } - } else if (lockExpression instanceof GrThisReferenceExpression) { - isLockedOnInstance = true; } elementToCheck = syncStatement; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/threading/GroovySynchronizationOnThisInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/threading/GroovySynchronizationOnThisInspection.java index 3efc17894287..b8113d0cf8dd 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/threading/GroovySynchronizationOnThisInspection.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/threading/GroovySynchronizationOnThisInspection.java @@ -22,7 +22,8 @@ import org.jetbrains.plugins.groovy.codeInspection.BaseInspection; import org.jetbrains.plugins.groovy.codeInspection.BaseInspectionVisitor; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrSynchronizedStatement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; +import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; public class GroovySynchronizationOnThisInspection extends BaseInspection { @@ -52,7 +53,7 @@ public class GroovySynchronizationOnThisInspection extends BaseInspection { public void visitSynchronizedStatement(GrSynchronizedStatement synchronizedStatement) { super.visitSynchronizedStatement(synchronizedStatement); final GrExpression lock = synchronizedStatement.getMonitor(); - if (lock == null || !(lock instanceof GrThisReferenceExpression)) { + if (lock == null || !(lock instanceof GrReferenceExpression && PsiUtil.isThisReference(lock))) { return; } registerError(lock); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/utils/BoolUtils.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/utils/BoolUtils.java index 20e7380641f3..8db91c50fceb 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/utils/BoolUtils.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/utils/BoolUtils.java @@ -17,6 +17,7 @@ package org.jetbrains.plugins.groovy.codeInspection.utils; import com.intellij.psi.tree.IElementType; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.intentions.utils.ComparisonUtils; import org.jetbrains.plugins.groovy.intentions.utils.ParenthesesUtils; import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; @@ -38,7 +39,7 @@ public class BoolUtils { return GroovyTokenTypes.mBNOT.equals(sign); } - public static boolean isTrue(GrCondition condition) { + public static boolean isTrue(@Nullable GrCondition condition) { if (condition == null) { return false; } @@ -68,7 +69,7 @@ public class BoolUtils { final GrExpression rhs = binaryExpression.getRightOperand(); assert rhs != null; return lhs.getText() + negatedComparison + rhs.getText(); - } else if (ParenthesesUtils.getPrecendence(condition) > + } else if (ParenthesesUtils.getPrecedence(condition) > ParenthesesUtils.PREFIX_PRECEDENCE) { return "!(" + condition.getText() + ')'; } else { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/utils/EquivalenceChecker.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/utils/EquivalenceChecker.java index 22985a39e48e..8aebf825a629 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/utils/EquivalenceChecker.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/utils/EquivalenceChecker.java @@ -54,10 +54,8 @@ public class EquivalenceChecker { super(); } - private static final int THIS_EXPRESSION = 0; private static final int LITERAL_EXPRESSION = 1; private static final int REFERENCE_EXPRESSION = 3; - private static final int SUPER_EXPRESSION = 4; private static final int CALL_EXPRESSION = 5; private static final int NEW_EXPRESSION = 6; private static final int ARRAY_LITERAL_EXPRESSION = 7; @@ -355,7 +353,9 @@ public class EquivalenceChecker { return openBlocksAreEquivalent(block1, block2); } - private static boolean openBlocksAreEquivalent(GrOpenBlock block1, GrOpenBlock block2) { + private static boolean openBlocksAreEquivalent(@Nullable GrOpenBlock block1, @Nullable GrOpenBlock block2) { + if (block1 == null || block2 == null) return false; + final GrStatement[] statements1 = block1.getStatements(); final GrStatement[] statements2 = block2.getStatements(); if (statements1.length != statements2.length) { @@ -418,9 +418,6 @@ public class EquivalenceChecker { return false; } switch (type1) { - case THIS_EXPRESSION: - case SUPER_EXPRESSION: - return true; case LITERAL_EXPRESSION: case REFERENCE_EXPRESSION: final String text1 = expToCompare1.getText(); @@ -460,8 +457,8 @@ public class EquivalenceChecker { return typecastExpressionsAreEquivalent((GrTypeCastExpression) expToCompare1, (GrTypeCastExpression) expToCompare2); case SAFE_CAST_EXPRESSION: - return safecastExpressionsAreEquivalent((GrSafeCastExpression) expToCompare1, - (GrSafeCastExpression) expToCompare2); + return safeCastExpressionsAreEquivalent((GrSafeCastExpression)expToCompare1, + (GrSafeCastExpression)expToCompare2); case INSTANCEOF_EXPRESSION: return instanceofExpressionsAreEquivalent((GrInstanceOfExpression) expToCompare1, (GrInstanceOfExpression) expToCompare2); @@ -538,8 +535,12 @@ public class EquivalenceChecker { if (!expressionsAreEquivalent(operand1, operand2)) { return false; } - final PsiType type1 = expression1.getTypeElement().getType(); - final PsiType type2 = expression2.getTypeElement().getType(); + GrTypeElement typeElement1 = expression1.getTypeElement(); + GrTypeElement typeElement2 = expression2.getTypeElement(); + if (typeElement1 == null || typeElement2 == null) return false; + + final PsiType type1 = typeElement1.getType(); + final PsiType type2 = typeElement2.getType(); return typesAreEquivalent(type1, type2); } @@ -561,7 +562,7 @@ public class EquivalenceChecker { return typesAreEquivalent(type1, type2); } - private static boolean safecastExpressionsAreEquivalent(GrSafeCastExpression expression1, + private static boolean safeCastExpressionsAreEquivalent(GrSafeCastExpression expression1, GrSafeCastExpression expression2) { final GrExpression operand1 = expression1.getOperand(); final GrExpression operand2 = expression2.getOperand(); @@ -591,7 +592,7 @@ public class EquivalenceChecker { return argumentListsAreEquivalent(methodExp1.getArgumentList(), methodExp2.getArgumentList()); } - private static boolean argumentListsAreEquivalent(GrArgumentList list1, GrArgumentList list2) { + private static boolean argumentListsAreEquivalent(@Nullable GrArgumentList list1, @Nullable GrArgumentList list2) { if (list1 == null && list2 == null) { return true; } @@ -773,12 +774,6 @@ public class EquivalenceChecker { } private static int getExpressionType(@Nullable GrExpression exp) { - if (exp instanceof GrThisReferenceExpression) { - return THIS_EXPRESSION; - } - if (exp instanceof GrSuperReferenceExpression) { - return SUPER_EXPRESSION; - } if (exp instanceof GrArrayDeclaration) { return ARRAY_LITERAL_EXPRESSION; } @@ -830,7 +825,7 @@ public class EquivalenceChecker { if (exp instanceof GrClosableBlock) { return CLOSABLE_BLOCK_EXPRESSION; } - return -1; // Type of expression can be defined in thirdparty plugins. See issue #IDEA-59846 + return -1; // Type of expression can be defined in third party plugins. See issue #IDEA-59846 } private static int getStatementType(@Nullable GrStatement statement) { @@ -880,6 +875,6 @@ public class EquivalenceChecker { return ASSERT_STATEMENT; } - return -1; // Type of expression can be defined in thirdparty plugins. See issue #IDEA-59846 + return -1; // Type of expression can be defined in third party plugins. See issue #IDEA-59846 } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyCodeFragmentFactory.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyCodeFragmentFactory.java index 7f658f565e36..f7be975391fe 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyCodeFragmentFactory.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyCodeFragmentFactory.java @@ -41,8 +41,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrSuperReferenceExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition; import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement; @@ -124,7 +122,10 @@ public class GroovyCodeFragmentFactory extends CodeFragmentFactory { //javaText.append("System.out.println(java.util.Arrays.toString(new Exception().getStackTrace()));\n"); //javaText.append("System.out.println(\"\\\\[([^,()]+\\\\$\\\\$)[A-Za-z0-9]{8}(\\\\.[^,()]+)\\\\(" + s + ":\\\\d+\\\\), (\\\\1[A-Za-z0-9]{8}\\\\2\\\\(Unknown Source\\\\), |.+com\\\\.springsource\\\\.loaded\\\\.).+\")\n"); - javaText.append("if (java.util.Arrays.toString(new Exception().getStackTrace()).matches(\"\\\\[([^,()]+\\\\$\\\\$)[A-Za-z0-9]{8}(\\\\.[^,()]+)\\\\(" + s + ":\\\\d+\\\\), (\\\\1[A-Za-z0-9]{8}\\\\2\\\\(Unknown Source\\\\), $OR$.+com\\\\.springsource\\\\.loaded\\\\.).+\")) {\n"); + javaText.append( + "if (java.util.Arrays.toString(new Exception().getStackTrace()).matches(\"\\\\[([^,()]+\\\\$\\\\$)[A-Za-z0-9]{8}(\\\\.[^,()]+)\\\\(") + .append(s) + .append(":\\\\d+\\\\), (\\\\1[A-Za-z0-9]{8}\\\\2\\\\(Unknown Source\\\\), $OR$.+com\\\\.springsource\\\\.loaded\\\\.).+\")) {\n"); javaText.append(" |thiz0 = thiz;\n"); javaText.append(" } else {\n"); javaText.append(" |thiz0 = this;\n"); @@ -144,9 +145,8 @@ public class GroovyCodeFragmentFactory extends CodeFragmentFactory { javaText.append("final java.lang.ClassLoader |parentLoader = |clazz.getClassLoader();\n" + " final groovy.lang.GroovyClassLoader |loader = new groovy.lang.GroovyClassLoader(|parentLoader);\n" + " final java.lang.Class |c = |loader.parseClass("); - javaText.append("\"" + IMPORTS + "class DUMMY" + new Random().nextInt(239) + " { " + - "public groovy.lang.Closure " + - EVAL_NAME + " = {" + TEXT + "}}\""); + javaText.append("\"" + IMPORTS + "class DUMMY").append(new Random().nextInt(239)).append(" { ").append("public groovy.lang.Closure ") + .append(EVAL_NAME).append(" = {").append(TEXT).append("}}\""); javaText.append(", \"DUMMY.groovy\");\n" + " int |i;\n" + " java.lang.reflect.Field[] |fields = |c.getFields();\n" + @@ -197,6 +197,16 @@ public class GroovyCodeFragmentFactory extends CodeFragmentFactory { super.visitReferenceExpression(referenceExpression); PsiElement resolved = referenceExpression.resolve(); + if (PsiUtil.isThisReference(referenceExpression)) { + replaceWithReference(referenceExpression, closure == null ? "delegate" : "owner"); + return; + } + + if (PsiUtil.isSuperReference(referenceExpression)) { + replaceWithReference(referenceExpression, closure == null ? "delegate" : "owner"); + return; + } + if (resolved instanceof PsiMethod && "getDelegate".equals(((PsiMethod) resolved).getName()) && closure != null) { replaceWithReference(referenceExpression, "owner"); return; @@ -235,18 +245,6 @@ public class GroovyCodeFragmentFactory extends CodeFragmentFactory { } - @Override - public void visitThisExpression(final GrThisReferenceExpression thisExpression) { - super.visitThisExpression(thisExpression); - replaceWithReference(thisExpression, closure == null ? "delegate" : "owner"); - } - - @Override - public void visitSuperExpression(final GrSuperReferenceExpression superExpression) { - super.visitSuperExpression(superExpression); - replaceWithReference(superExpression, closure == null ? "delegate" : "owner"); - } - private void replaceWithReference(GrExpression expr, final String exprText) { replacements.put(expr, exprText); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyEditorTextProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyEditorTextProvider.java index 4a7bff3c3751..6e72bc9533d0 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyEditorTextProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/debugger/GroovyEditorTextProvider.java @@ -29,7 +29,6 @@ import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression; import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil; /** @@ -77,9 +76,6 @@ public class GroovyEditorTextProvider implements EditorTextProvider { } } - if (parent instanceof GrThisReferenceExpression) { - return parent; - } return null; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/GroovyConstructorUsagesSearcher.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/GroovyConstructorUsagesSearcher.java index 092a0179445c..2628614ae01a 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/GroovyConstructorUsagesSearcher.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/GroovyConstructorUsagesSearcher.java @@ -381,7 +381,7 @@ public class GroovyConstructorUsagesSearcher extends QueryExecutorBase + if (ParenthesesUtils.getPrecedence(negated) > ParenthesesUtils.OR_PRECEDENCE) { return '(' + negated.getText() + ')'; } @@ -112,7 +112,7 @@ public class DemorgansLawIntention extends MutablyNamedIntention { final GrExpression rhs = binaryExpression.getRightOperand(); assert rhs != null; return lhs.getText() + negatedComparison + rhs.getText(); - } else if (ParenthesesUtils.getPrecendence(condition) > + } else if (ParenthesesUtils.getPrecedence(condition) > ParenthesesUtils.PREFIX_PRECEDENCE) { return "!(" + condition.getText() + ')'; } else { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/MergeIfAndIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/MergeIfAndIntention.java index b49515c3eda8..0a2086c63d26 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/MergeIfAndIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/MergeIfAndIntention.java @@ -48,7 +48,7 @@ public class MergeIfAndIntention extends Intention { final GrExpression childCondition = childStatement.getCondition(); final String childConditionText; - if (ParenthesesUtils.getPrecendence(childCondition) + if (ParenthesesUtils.getPrecedence(childCondition) > ParenthesesUtils.AND_PRECEDENCE) { childConditionText = '(' + childCondition.getText() + ')'; } else { @@ -57,7 +57,7 @@ public class MergeIfAndIntention extends Intention { final GrExpression parentCondition = parentStatement.getCondition(); final String parentConditionText; - if (ParenthesesUtils.getPrecendence(parentCondition) + if (ParenthesesUtils.getPrecedence(parentCondition) > ParenthesesUtils.AND_PRECEDENCE) { parentConditionText = '(' + parentCondition.getText() + ')'; } else { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/SimplifyTernaryOperatorIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/SimplifyTernaryOperatorIntention.java index ad49289c47e8..477772a60073 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/SimplifyTernaryOperatorIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/control/SimplifyTernaryOperatorIntention.java @@ -93,7 +93,7 @@ public class SimplifyTernaryOperatorIntention extends Intention { @NotNull private static String getStringToPutIntoAndExpression(GrExpression expression) { String expressionText = expression.getText(); - if (ParenthesesUtils.AND_PRECEDENCE < ParenthesesUtils.getPrecendence(expression)) { + if (ParenthesesUtils.AND_PRECEDENCE < ParenthesesUtils.getPrecedence(expression)) { expressionText = "(" + expressionText + ")"; } return expressionText; @@ -102,7 +102,7 @@ public class SimplifyTernaryOperatorIntention extends Intention { @NotNull private static String getStringToPutIntoOrExpression(GrExpression expression) { String expressionText = expression.getText(); - if (ParenthesesUtils.OR_PRECEDENCE < ParenthesesUtils.getPrecendence(expression)) { + if (ParenthesesUtils.OR_PRECEDENCE < ParenthesesUtils.getPrecedence(expression)) { expressionText = "(" + expressionText + ")"; } return expressionText; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/strings/ConvertGStringToStringIntention.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/strings/ConvertGStringToStringIntention.java index 1c51f7715440..6d0799f5c60b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/strings/ConvertGStringToStringIntention.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/conversions/strings/ConvertGStringToStringIntention.java @@ -33,10 +33,10 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrReturnState import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrBinaryExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisSuperReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrStringInjection; import org.jetbrains.plugins.groovy.lang.psi.util.GrStringUtil; +import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; import java.util.ArrayList; @@ -112,7 +112,7 @@ public class ConvertGStringToStringIntention extends Intention { } private static String prepareExpression(GrExpression expr) { - if (expr instanceof GrThisSuperReferenceExpression) return expr.getText(); + if (PsiUtil.isThisOrSuperRef(expr)) return expr.getText(); String text = expr.getText(); final PsiType type = expr.getType(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/utils/BoolUtils.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/utils/BoolUtils.java index a954c3e382ba..9608a67c8cc4 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/utils/BoolUtils.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/utils/BoolUtils.java @@ -19,8 +19,10 @@ import com.intellij.psi.tree.IElementType; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrBinaryExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrParenthesizedExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrUnaryExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral; import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; @@ -100,7 +102,7 @@ public class BoolUtils { final GrExpression rhs = binaryExpression.getRightOperand(); assert rhs != null; return lhs.getText() + negatedComparison + rhs.getText(); - } else if (ParenthesesUtils.getPrecendence(condition) > + } else if (ParenthesesUtils.getPrecedence(condition) > ParenthesesUtils.PREFIX_PRECEDENCE) { return "!(" + condition.getText() + ')'; } else { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/utils/ParenthesesUtils.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/utils/ParenthesesUtils.java index 4c354de1c83a..e0e971704c93 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/utils/ParenthesesUtils.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/utils/ParenthesesUtils.java @@ -82,18 +82,16 @@ public class ParenthesesUtils { s_binaryOperatorPrecedence.put(GroovyTokenTypes.mCOMPARE_TO, EQUALITY_PRECEDENCE); } - public static int getPrecendence(GrExpression expression) { - if (expression instanceof GrThisReferenceExpression || - expression instanceof GrLiteral || - expression instanceof GrSuperReferenceExpression ) { + public static int getPrecedence(GrExpression expression) { + if (expression instanceof GrLiteral) { return LITERAL_PRECEDENCE; } if (expression instanceof GrReferenceExpression) { - final GrReferenceExpression referenceExpression = - (GrReferenceExpression) expression; + final GrReferenceExpression referenceExpression = (GrReferenceExpression)expression; if (referenceExpression.getQualifierExpression() != null) { return METHOD_CALL_PRECEDENCE; - } else { + } + else { return LITERAL_PRECEDENCE; } } @@ -105,11 +103,10 @@ public class ParenthesesUtils { return TYPE_CAST_PRECEDENCE; } if (expression instanceof GrUnaryExpression) { - return ((GrUnaryExpression)expression).isPostfix()?POSTFIX_PRECEDENCE:PREFIX_PRECEDENCE; + return ((GrUnaryExpression)expression).isPostfix() ? POSTFIX_PRECEDENCE : PREFIX_PRECEDENCE; } if (expression instanceof GrBinaryExpression) { - final GrBinaryExpression binaryExpression = - (GrBinaryExpression) expression; + final GrBinaryExpression binaryExpression = (GrBinaryExpression) expression; final IElementType sign = binaryExpression.getOperationTokenType(); return precedenceForBinaryOperator(sign); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GrReferenceAdjuster.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GrReferenceAdjuster.java index 0040d9dd6d20..f70bb124d849 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GrReferenceAdjuster.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GrReferenceAdjuster.java @@ -28,11 +28,14 @@ import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.psi.GrQualifiedReference; import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement; import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeArgumentList; import org.jetbrains.plugins.groovy.lang.psi.impl.GrReferenceElementImpl; +import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; /** * @author Max Medvedev @@ -63,7 +66,7 @@ public class GrReferenceAdjuster { if (element instanceof GrQualifiedReference && ((GrQualifiedReference)element).resolve() instanceof PsiClass) { result = shortenReferenceInner((GrQualifiedReference)element, addImports, incomplete); } - else if (element instanceof GrReferenceExpression && ((GrReferenceExpression)element).getQualifier() instanceof GrThisSuperReferenceExpression) { + else if (element instanceof GrReferenceExpression && PsiUtil.isSuperReference(((GrReferenceExpression)element).getQualifier())) { result = shortenReferenceInner((GrReferenceExpression)element, addImports, incomplete); } @@ -81,7 +84,7 @@ public class GrReferenceAdjuster { private static boolean shortenReferenceInner(GrQualifiedReference ref, boolean addImports, boolean incomplete) { final Qualifier qualifier = ref.getQualifier(); - if (qualifier == null || qualifier instanceof GrSuperReferenceExpression || cannotShortenInContext(ref)) { + if (qualifier == null || PsiUtil.isSuperReference(qualifier) || cannotShortenInContext(ref)) { return false; } @@ -173,7 +176,7 @@ public class GrReferenceAdjuster { } if (qualifier instanceof GrExpression) { - if (qualifier instanceof GrThisReferenceExpression) return true; + if (qualifier instanceof GrReferenceExpression && PsiUtil.isThisReference(qualifier)) return true; if (qualifier instanceof GrReferenceExpression && seemsToBeQualifiedClassName((GrExpression)qualifier)) { final PsiElement resolved = ((GrReferenceExpression)qualifier).resolve(); if (resolved instanceof PsiClass || resolved instanceof PsiPackage) return true; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovyChangeUtilSupport.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovyChangeUtilSupport.java index dfb5e0f0f2f8..176fbddbb5e0 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovyChangeUtilSupport.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovyChangeUtilSupport.java @@ -31,6 +31,7 @@ import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes; import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement; import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement; +import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; import java.util.Map; @@ -67,16 +68,20 @@ public class GroovyChangeUtilSupport implements TreeCopyHandler { public void encodeInformation(final TreeElement element, final ASTNode original, final Map encodingState) { if (original instanceof CompositeElement) { - if (original.getElementType() == GroovyElementTypes.REFERENCE_ELEMENT || original.getElementType() == GroovyElementTypes.REFERENCE_EXPRESSION) { - final GroovyResolveResult result = ((GrReferenceElement)original.getPsi()).advancedResolve(); - if (result != null) { - final PsiElement target = result.getElement(); + if (original.getElementType() == GroovyElementTypes.REFERENCE_ELEMENT || + original.getElementType() == GroovyElementTypes.REFERENCE_EXPRESSION) { + PsiElement psi = original.getPsi(); + if (!PsiUtil.isThisOrSuperRef(psi)) { + final GroovyResolveResult result = ((GrReferenceElement)psi).advancedResolve(); + if (result != null) { + final PsiElement target = result.getElement(); - if (target instanceof PsiClass || - (target instanceof PsiMethod || target instanceof PsiField) && - ((PsiMember) target).hasModifierProperty(PsiModifier.STATIC) && - result.getCurrentFileResolveContext() instanceof GrImportStatement) { - element.putCopyableUserData(REFERENCED_MEMBER_KEY, (PsiMember) target); + if (target instanceof PsiClass || + (target instanceof PsiMethod || target instanceof PsiField) && + ((PsiMember)target).hasModifierProperty(PsiModifier.STATIC) && + result.getCurrentFileResolveContext() instanceof GrImportStatement) { + element.putCopyableUserData(REFERENCED_MEMBER_KEY, (PsiMember)target); + } } } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyElementTypes.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyElementTypes.java index 425b8398908a..8d080a6d8f38 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyElementTypes.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyElementTypes.java @@ -235,8 +235,6 @@ public interface GroovyElementTypes extends GroovyTokenTypes, GroovyDocElementTy GroovyElementType SPREAD_ARGUMENT = new GroovyElementType("Spread argument"); GroovyElementType ARGUMENT_LABEL = new GroovyElementType("Argument label"); GroovyElementType REFERENCE_EXPRESSION = new GroovyElementType("Reference expressions"); - GroovyElementType THIS_REFERENCE_EXPRESSION = new GroovyElementType("This reference expressions"); - GroovyElementType SUPER_REFERENCE_EXPRESSION = new GroovyElementType("Super reference expressions"); GroovyElementType NEW_EXPRESSION = new GroovyElementType("New expressions"); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyPsiCreator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyPsiCreator.java index ecbecfc4f1f5..37dcc02bb3fe 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyPsiCreator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyPsiCreator.java @@ -232,8 +232,6 @@ public class GroovyPsiCreator implements GroovyElementTypes { if (elem == REGEX) return new GrRegexImpl(node); if (elem == GSTRING_INJECTION) return new GrStringInjectionImpl(node); if (elem == REFERENCE_EXPRESSION) return new GrReferenceExpressionImpl(node); - if (elem == THIS_REFERENCE_EXPRESSION) return new GrThisReferenceExpressionImpl(node); - if (elem == SUPER_REFERENCE_EXPRESSION) return new GrSuperReferenceExpressionImpl(node); if (elem == PARENTHESIZED_EXPRESSION) return new GrParenthesizedExpressionImpl(node); if (elem == NEW_EXPRESSION) return new GrNewExpressionImpl(node); if (elem == ANONYMOUS_CLASS_DEFINITION) return new GrAnonymousClassDefinitionImpl(node); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/constructor/ConstructorBody.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/constructor/ConstructorBody.java index 1c6e6fc18712..30ddee8de3c5 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/constructor/ConstructorBody.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/constructor/ConstructorBody.java @@ -70,13 +70,13 @@ public class ConstructorBody implements GroovyElementTypes { if (ParserUtils.lookAhead(builder, kTHIS, mLPAREN)) { final PsiBuilder.Marker marker = builder.mark(); ParserUtils.getToken(builder, kTHIS); - marker.done(THIS_REFERENCE_EXPRESSION); + marker.done(REFERENCE_EXPRESSION); result = true; } if (ParserUtils.lookAhead(builder, kSUPER, mLPAREN)) { final PsiBuilder.Marker marker = builder.mark(); ParserUtils.getToken(builder, kSUPER); - marker.done(SUPER_REFERENCE_EXPRESSION); + marker.done(REFERENCE_EXPRESSION); result = true; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arithmetic/PathExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arithmetic/PathExpression.java index feb2427e66eb..14fe82f7e05a 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arithmetic/PathExpression.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arithmetic/PathExpression.java @@ -41,7 +41,7 @@ import static org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expres public class PathExpression implements GroovyElementTypes { public static boolean parse(PsiBuilder builder, GroovyParser parser) { - return parsePathExprQualifierForExprStatement(builder, parser) != PathExpression.Result.WRONG_WAY; + return parsePathExprQualifierForExprStatement(builder, parser) != WRONG_WAY; } public enum Result {INVOKED_EXPR, METHOD_CALL, WRONG_WAY, LITERAL} @@ -70,10 +70,10 @@ public class PathExpression implements GroovyElementTypes { PsiBuilder.Marker argsMarker = builder.mark(); argsMarker.done(ARGUMENTS); ParserUtils.getToken(builder, mNLS); - result = pathElementParse(builder, newMarker, parser, qualifierType, METHOD_CALL); + result = pathElementParse(builder, newMarker, parser, METHOD_CALL); } else { - result = pathElementParse(builder, newMarker, parser, qualifierType, INVOKED_EXPR); + result = pathElementParse(builder, newMarker, parser, INVOKED_EXPR); } } else { @@ -102,10 +102,9 @@ public class PathExpression implements GroovyElementTypes { private static final TokenSet DOTS = TokenSet.create(mSPREAD_DOT, mOPTIONAL_DOT, mMEMBER_POINTER, mDOT); private static Result pathElementParse(PsiBuilder builder, - PsiBuilder.Marker marker, - GroovyParser parser, - IElementType qualifierType, - Result result) { + PsiBuilder.Marker marker, + GroovyParser parser, + Result result) { GroovyElementType res; @@ -117,12 +116,7 @@ public class PathExpression implements GroovyElementTypes { ParserUtils.getToken(builder, DOTS); ParserUtils.getToken(builder, mNLS); TypeArguments.parseTypeArguments(builder, true); - if (kTHIS.equals(builder.getTokenType()) || kSUPER.equals(builder.getTokenType())) { - res = parseThisSuperExpression(builder, qualifierType); - } - else { - res = namePartParse(builder, parser); - } + res = namePartParse(builder, parser); if (!res.equals(WRONGWAY)) { PsiBuilder.Marker newMarker = marker.precede(); marker.done(res); @@ -130,10 +124,10 @@ public class PathExpression implements GroovyElementTypes { PsiBuilder.Marker argsMarker = builder.mark(); argsMarker.done(ARGUMENTS); ParserUtils.getToken(builder, mNLS); - result = pathElementParse(builder, newMarker, parser, res, METHOD_CALL); + result = pathElementParse(builder, newMarker, parser, METHOD_CALL); } else { - result = pathElementParse(builder, newMarker, parser, res, INVOKED_EXPR); + result = pathElementParse(builder, newMarker, parser, INVOKED_EXPR); } } else { @@ -145,12 +139,12 @@ public class PathExpression implements GroovyElementTypes { PrimaryExpression.methodCallArgsParse(builder, parser); if (checkForLCurly(builder)) { ParserUtils.getToken(builder, mNLS); - result = pathElementParse(builder, marker, parser, qualifierType, METHOD_CALL); + result = pathElementParse(builder, marker, parser, METHOD_CALL); } else { PsiBuilder.Marker newMarker = marker.precede(); marker.done(PATH_METHOD_CALL); - result = pathElementParse(builder, newMarker, parser, qualifierType, METHOD_CALL); + result = pathElementParse(builder, newMarker, parser, METHOD_CALL); } } else if (checkForLCurly(builder)) { @@ -158,12 +152,12 @@ public class PathExpression implements GroovyElementTypes { appendedBlockParse(builder, parser); if (checkForLCurly(builder)) { ParserUtils.getToken(builder, mNLS); - result = pathElementParse(builder, marker, parser, qualifierType, METHOD_CALL); + result = pathElementParse(builder, marker, parser, METHOD_CALL); } else { PsiBuilder.Marker newMarker = marker.precede(); marker.done(PATH_METHOD_CALL); - result = pathElementParse(builder, newMarker, parser, PATH_METHOD_CALL, METHOD_CALL); + result = pathElementParse(builder, newMarker, parser, METHOD_CALL); } } else if (checkForArrayAccess(builder)) { @@ -174,10 +168,10 @@ public class PathExpression implements GroovyElementTypes { PsiBuilder.Marker argsMarker = builder.mark(); argsMarker.done(ARGUMENTS); ParserUtils.getToken(builder, mNLS); - result = pathElementParse(builder, newMarker, parser, PATH_INDEX_PROPERTY, METHOD_CALL); + result = pathElementParse(builder, newMarker, parser, METHOD_CALL); } else { - result = pathElementParse(builder, newMarker, parser, PATH_INDEX_PROPERTY, INVOKED_EXPR); + result = pathElementParse(builder, newMarker, parser, INVOKED_EXPR); } } else { @@ -196,23 +190,6 @@ public class PathExpression implements GroovyElementTypes { !ParserUtils.lookAhead(builder, mLBRACK, mNLS, mCOLON); } - private static GroovyElementType parseThisSuperExpression(PsiBuilder builder, IElementType qualifierType) { - if (qualifierType != REFERENCE_EXPRESSION) { - return WRONGWAY; - } - final IElementType tokenType = builder.getTokenType(); - builder.advanceLexer(); - final GroovyElementType type; - if (kTHIS.equals(tokenType)) { - type = THIS_REFERENCE_EXPRESSION; - } - else { - type = SUPER_REFERENCE_EXPRESSION; - } - - return type; - } - /** * Property selector parsing * diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/PrimaryExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/PrimaryExpression.java index 8d284aa997b9..e2f6eab55964 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/PrimaryExpression.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/PrimaryExpression.java @@ -47,21 +47,13 @@ public class PrimaryExpression implements GroovyElementTypes { ParserUtils.eatElement(builder, BUILT_IN_TYPE_EXPRESSION); return BUILT_IN_TYPE_EXPRESSION; } - if (kTHIS == tokenType) { - ParserUtils.eatElement(builder, THIS_REFERENCE_EXPRESSION); - return THIS_REFERENCE_EXPRESSION; - } - if (kSUPER == tokenType) { - ParserUtils.eatElement(builder, SUPER_REFERENCE_EXPRESSION); - return SUPER_REFERENCE_EXPRESSION; - } if (kNEW == tokenType) { PsiBuilder.Marker marker = builder.mark(); final GroovyElementType type = newExprParse(builder, parser); marker.done(type); return type; } - if (mIDENT == tokenType) { + if (mIDENT == tokenType || kSUPER == tokenType || kTHIS == tokenType) { ParserUtils.eatElement(builder, REFERENCE_EXPRESSION); return REFERENCE_EXPRESSION; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/StringConstructorExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/StringConstructorExpression.java index e4ac24ae22b7..57432c1d79e4 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/StringConstructorExpression.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/StringConstructorExpression.java @@ -18,6 +18,7 @@ package org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions. import com.intellij.lang.PsiBuilder; import com.intellij.lang.PsiBuilder.Marker; +import com.intellij.psi.tree.IElementType; import org.jetbrains.plugins.groovy.GroovyBundle; import org.jetbrains.plugins.groovy.lang.lexer.GroovyElementType; import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes; @@ -60,18 +61,13 @@ public class StringConstructorExpression implements GroovyElementTypes { final Marker injection = builder.mark(); ParserUtils.getToken(builder, mDOLLAR); ParserUtils.getToken(builder, mSTAR); - if (mIDENT.equals(builder.getTokenType())) { + IElementType tokenType = builder.getTokenType(); + if (mIDENT == tokenType || kTHIS==tokenType || kSUPER==tokenType) { PathExpression.parse(builder, parser); } - else if (mLCURLY.equals(builder.getTokenType())) { + else if (mLCURLY == tokenType) { OpenOrClosableBlock.parseClosableBlock(builder, parser); } - else if (kTHIS.equals(builder.getTokenType())) { - ParserUtils.eatElement(builder, THIS_REFERENCE_EXPRESSION); - } - else if (kSUPER.equals(builder.getTokenType())) { - ParserUtils.eatElement(builder, SUPER_REFERENCE_EXPRESSION); - } else { ParserUtils.wrapError(builder, GroovyBundle.message("identifier.or.block.expected")); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyElementVisitor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyElementVisitor.java index ab15bfcb5bc6..967fff60b4ca 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyElementVisitor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyElementVisitor.java @@ -184,18 +184,6 @@ public abstract class GroovyElementVisitor { visitExpression(referenceExpression); } - public void visitThisExpression(GrThisReferenceExpression thisExpression) { - visitThisSuperReferenceExpression(thisExpression); - } - - public void visitSuperExpression(GrSuperReferenceExpression superExpression) { - visitThisSuperReferenceExpression(superExpression); - } - - public void visitThisSuperReferenceExpression(GrThisSuperReferenceExpression expression) { - visitExpression(expression); - } - public void visitCastExpression(GrTypeCastExpression typeCastExpression) { visitExpression(typeCastExpression); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyPsiElementFactory.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyPsiElementFactory.java index a9eb766d1115..6b3a17c06965 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyPsiElementFactory.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/GroovyPsiElementFactory.java @@ -37,7 +37,10 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArg import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrCaseSection; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrApplicationStatement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrParenthesizedExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; @@ -62,7 +65,7 @@ public abstract class GroovyPsiElementFactory implements JVMElementFactory { public abstract GrCodeReferenceElement createCodeReferenceElementFromText(String text); - public abstract GrThisReferenceExpression createThisExpression(PsiManager manager, PsiClass psiClass); + public abstract GrReferenceExpression createThisExpression(PsiManager manager, PsiClass psiClass); public abstract GrBlockStatement createBlockStatementFromText(String text, @Nullable PsiElement context); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/SpreadState.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/SpreadState.java index c5eec5f1c27d..891c61d6d763 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/SpreadState.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/SpreadState.java @@ -27,14 +27,15 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUt public final class SpreadState { public static final Key SPREAD_STATE = Key.create("Spread state"); - private final PsiType containerType; + @Nullable private final PsiType containerType; @Nullable private final SpreadState innerState; - public SpreadState(PsiType type, @Nullable SpreadState state) { + public SpreadState(@Nullable PsiType type, @Nullable SpreadState state) { containerType = type; innerState = state; } + @Nullable public PsiType getContainerType() { return containerType; } @@ -48,7 +49,8 @@ public final class SpreadState { return new SpreadState(type, state); } - public static PsiType apply(PsiType item, @Nullable SpreadState state, Project project) { + @Nullable + public static PsiType apply(@Nullable PsiType item, @Nullable SpreadState state, Project project) { if (state == null) return item; return apply(TypesUtil.createSimilarCollection(state.getContainerType(), project, item), state.getInnerState(), project); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/GrConstructorInvocation.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/GrConstructorInvocation.java index 19f049ea6fd1..922f5bbba76a 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/GrConstructorInvocation.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/GrConstructorInvocation.java @@ -20,7 +20,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrConstructorCall; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisSuperReferenceExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; /** * User: Dmitry.Krasilschikov @@ -31,7 +31,7 @@ public interface GrConstructorInvocation extends GrStatement, GrConstructorCall boolean isThisCall(); - GrThisSuperReferenceExpression getThisOrSuperKeyword(); + GrReferenceExpression getInvokedExpression(); @Nullable PsiClass getDelegatedClass(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrThisSuperReferenceExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrThisSuperReferenceExpression.java index 2f240940954b..3284a9c75ad7 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrThisSuperReferenceExpression.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/api/statements/expressions/GrThisSuperReferenceExpression.java @@ -15,11 +15,20 @@ */ package org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions; +import com.intellij.psi.PsiElement; import com.intellij.psi.PsiPolyVariantReference; +import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.lang.psi.GrQualifiedReference; /** * @author Maxim.Medvedev */ public interface GrThisSuperReferenceExpression extends GrExpression, PsiPolyVariantReference, GrQualifiedReference { + @NotNull + @Override + PsiElement getReferenceNameElement(); + + @NotNull + @Override + String getReferenceName(); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyPsiElementFactoryImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyPsiElementFactoryImpl.java index 4cb36793b0e8..2271338f4765 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyPsiElementFactoryImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyPsiElementFactoryImpl.java @@ -671,7 +671,7 @@ public class GroovyPsiElementFactoryImpl extends GroovyPsiElementFactory { } @Override - public GrThisReferenceExpression createThisExpression(PsiManager manager, @Nullable PsiClass psiClass) { + public GrReferenceExpression createThisExpression(PsiManager manager, @Nullable PsiClass psiClass) { final String text; if (psiClass == null) { text = "this"; @@ -679,8 +679,7 @@ public class GroovyPsiElementFactoryImpl extends GroovyPsiElementFactory { else { text = psiClass.getQualifiedName() + ".this"; } - final GroovyFileImpl dummy = createDummyFile(text); - return (GrThisReferenceExpression)dummy.getStatements()[0]; + return createReferenceExpressionFromText(text); } @Override diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrConstructorInvocationImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrConstructorInvocationImpl.java index 611ddfd9c3ec..a591ed55c994 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrConstructorInvocationImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/GrConstructorInvocationImpl.java @@ -17,16 +17,16 @@ package org.jetbrains.plugins.groovy.lang.psi.impl.statements; import com.intellij.lang.ASTNode; import com.intellij.psi.*; -import com.intellij.psi.tree.TokenSet; +import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.TypeConversionUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes; +import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor; import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrConstructorInvocation; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisSuperReferenceExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl; import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrCallImpl; @@ -52,18 +52,25 @@ public class GrConstructorInvocationImpl extends GrCallImpl implements GrConstru } public boolean isSuperCall() { - return findChildByType(GroovyElementTypes.SUPER_REFERENCE_EXPRESSION) != null; + return getKeywordType() == GroovyTokenTypes.kSUPER; } public boolean isThisCall() { - return findChildByType(GroovyElementTypes.THIS_REFERENCE_EXPRESSION) != null; + return getKeywordType() == GroovyTokenTypes.kTHIS; } - private static final TokenSet THIS_OR_SUPER_SET = - TokenSet.create(GroovyElementTypes.THIS_REFERENCE_EXPRESSION, GroovyElementTypes.SUPER_REFERENCE_EXPRESSION); + @Nullable + private IElementType getKeywordType() { + GrReferenceExpression keyword = getInvokedExpression(); + PsiElement refElement = keyword.getReferenceNameElement(); + if (refElement == null) return null; - public GrThisSuperReferenceExpression getThisOrSuperKeyword() { - return (GrThisSuperReferenceExpression)findNotNullChildByType(THIS_OR_SUPER_SET); + return refElement.getNode().getElementType(); + } + + + public GrReferenceExpression getInvokedExpression() { + return findNotNullChildByClass(GrReferenceExpression.class); } @NotNull @@ -75,7 +82,8 @@ public class GrConstructorInvocationImpl extends GrCallImpl implements GrConstru PsiSubstitutor substitutor; if (isThisCall()) { substitutor = PsiSubstitutor.EMPTY; - } else { + } + else { PsiClass enclosing = PsiUtil.getContextClass(this); assert enclosing != null; substitutor = TypeConversionUtil.getSuperClassSubstitutor(clazz, enclosing, PsiSubstitutor.EMPTY); @@ -85,7 +93,7 @@ public class GrConstructorInvocationImpl extends GrCallImpl implements GrConstru incompleteCode, false); final ResolveState state = ResolveState.initial().put(PsiSubstitutor.KEY, substitutor); clazz.processDeclarations(processor, state, null, this); - ResolveUtil.processNonCodeMembers(thisType, processor, getThisOrSuperKeyword(), state); + ResolveUtil.processNonCodeMembers(thisType, processor, getInvokedExpression(), state); return processor.getCandidates(); } @@ -118,11 +126,6 @@ public class GrConstructorInvocationImpl extends GrCallImpl implements GrConstru return null; } - @NotNull - public String getCanonicalText() { - return getText(); //TODO - } - @NotNull @Override public GroovyResolveResult[] getCallVariants(@Nullable GrExpression upToArgument) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/CompleteReferenceExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/CompleteReferenceExpression.java index 124fbd9f9994..f9a5b1c3ebd3 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/CompleteReferenceExpression.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/CompleteReferenceExpression.java @@ -46,7 +46,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; @@ -133,8 +132,8 @@ public class CompleteReferenceExpression { if (refExpr.getDotTokenType() != GroovyTokenTypes.mSPREAD_DOT) { getVariantsFromQualifier(refExpr, processor, qualifier); - if (qualifier instanceof GrReferenceExpression && "class".equals(((GrReferenceExpression)qualifier).getReferenceName()) || - qualifier instanceof GrThisReferenceExpression) { + if (qualifier instanceof GrReferenceExpression && + ("class".equals(((GrReferenceExpression)qualifier).getReferenceName()) || PsiUtil.isThisReference(qualifier) && !PsiUtil.isInstanceThisRef(qualifier))) { processIfJavaLangClass(refExpr, processor, qualifier.getType()); } } @@ -261,7 +260,7 @@ public class CompleteReferenceExpression { } else { getVariantsFromQualifierType(refExpr, processor, qualifierType, project); - if (qualifier instanceof GrReferenceExpression) { + if (qualifier instanceof GrReferenceExpression && !PsiUtil.isSuperReference(qualifier) && !PsiUtil.isInstanceThisRef(qualifier)) { PsiElement resolved = ((GrReferenceExpression)qualifier).resolve(); if (resolved instanceof PsiClass) { ////omitted .class GlobalSearchScope scope = refExpr.getResolveScope(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java index 0bde09c323aa..3b62d3cf674d 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrReferenceExpressionImpl.java @@ -20,6 +20,7 @@ import com.intellij.codeInsight.completion.CompletionParameters; import com.intellij.codeInsight.completion.PrefixMatcher; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.lang.ASTNode; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.NullableComputable; import com.intellij.openapi.util.Pair; @@ -43,6 +44,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.GroovyFileType; import org.jetbrains.plugins.groovy.codeInsight.GrReassignedLocalVarsChecker; import org.jetbrains.plugins.groovy.codeInsight.GroovyTargetElementEvaluator; +import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.lexer.TokenSets; import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor; import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; @@ -81,6 +83,8 @@ import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.mMEMBER_P */ public class GrReferenceExpressionImpl extends GrReferenceElementImpl implements GrReferenceExpression { + private static final Logger LOG = Logger.getInstance(GrReferenceExpressionImpl.class); + public GrReferenceExpressionImpl(@NotNull ASTNode node) { super(node); } @@ -145,9 +149,25 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl results = new ArrayList(); + if (GrReferenceResolveUtil.resolveThisExpression(this, results)) { + return results.toArray(new GroovyResolveResult[results.size()]); + } + } + else if (nameType == GroovyTokenTypes.kSUPER) { + ArrayList results = new ArrayList(); + if (GrReferenceResolveUtil.resolveSuperExpression(this, results)) { + return results.toArray(new GroovyResolveResult[results.size()]); + } + } + EnumSet kinds = getParent() instanceof GrReferenceExpression ? ResolverProcessor.RESOLVE_KINDS_CLASS_PACKAGE @@ -213,11 +233,12 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl 0) { for (GroovyResolveResult candidate : fieldCandidates) { PsiElement element = candidate.getElement(); + LOG.assertTrue(element != null, candidate); if (GroovyRefactoringUtil.isLocalVariable(element)) { preferVar = true; break; @@ -335,7 +356,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl>() { @Override @@ -347,7 +368,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl doResolveByShape(boolean allVariants, @Nullable GrExpression upToArgument) { final String name = getReferenceName(); - assert name != null; + LOG.assertTrue(name != null); final MethodResolverProcessor shapeProcessor = createMethodProcessor(allVariants, name, true, upToArgument); processMethods(shapeProcessor); @@ -359,7 +380,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl results) { + GrExpression qualifier = ref.getQualifier(); + + if (qualifier == null) { + final PsiElement parent = ref.getParent(); + if (parent instanceof GrConstructorInvocation) { + GroovyResolveResult[] res = ((GrConstructorInvocation)parent).multiResolve(false); + ContainerUtil.addAll(results, res); + return true; + } + + PsiClass aClass = PsiUtil.getContextClass(ref); + if (aClass == null) return false; + + results.add(new GroovyResolveResultImpl(aClass, null, null, PsiSubstitutor.EMPTY, true, true)); + return true; + } + else { + if (!(qualifier instanceof GrReferenceExpression)) return false; + + GroovyResolveResult result = ((GrReferenceExpression)qualifier).advancedResolve(); + PsiElement resolved = result.getElement(); + if (!(resolved instanceof PsiClass)) return false; + if (!PsiUtil.hasEnclosingInstanceInScope((PsiClass)resolved, ref, false)) return false; + + results.add(result); + return true; + } + } + + public static boolean resolveSuperExpression(GrReferenceExpression ref, List results) { + GrExpression qualifier = ref.getQualifier(); + + PsiClass aClass; + if (qualifier == null) { + final PsiElement parent = ref.getParent(); + if (parent instanceof GrConstructorInvocation) { + GroovyResolveResult[] res = ((GrConstructorInvocation)parent).multiResolve(false); + ContainerUtil.addAll(results, res); + return true; + } + + aClass = PsiUtil.getContextClass(ref); + if (aClass == null) return false; + } + else { + if (!(qualifier instanceof GrReferenceExpression)) return false; + + GroovyResolveResult result = ((GrReferenceExpression)qualifier).advancedResolve(); + PsiElement resolved = result.getElement(); + if (!(resolved instanceof PsiClass)) return false; + if (!PsiUtil.hasEnclosingInstanceInScope((PsiClass)resolved, ref, false)) return false; + + aClass = (PsiClass)resolved; + } + PsiClass superClass = aClass.getSuperClass(); + if (superClass == null) return true; //no super class, but the reference is definitely super-reference + + PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(superClass, aClass, PsiSubstitutor.EMPTY); + results.add(new GroovyResolveResultImpl(superClass, null, null, superClassSubstitutor, true, true)); + return true; + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrSuperReferenceExpressionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrSuperReferenceExpressionImpl.java index 4d32c00f5a7d..61365ae5c007 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrSuperReferenceExpressionImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrSuperReferenceExpressionImpl.java @@ -76,7 +76,6 @@ public class GrSuperReferenceExpressionImpl extends GrThisSuperReferenceExpressi } public void accept(GroovyElementVisitor visitor) { - visitor.visitSuperExpression(this); } public String toString() { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisReferenceExpressionImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisReferenceExpressionImpl.java index dbc5d6c81dc9..9e7a4ebeede3 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisReferenceExpressionImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisReferenceExpressionImpl.java @@ -78,7 +78,6 @@ public class GrThisReferenceExpressionImpl extends GrThisSuperReferenceExpressio } public void accept(GroovyElementVisitor visitor) { - visitor.visitThisExpression(this); } public String toString() { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisSuperReferenceExpressionBase.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisSuperReferenceExpressionBase.java index 73bf660b7c14..15e0ea7571b8 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisSuperReferenceExpressionBase.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/GrThisSuperReferenceExpressionBase.java @@ -11,14 +11,15 @@ import com.intellij.util.ArrayUtil; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes; import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrConstructorInvocation; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisSuperReferenceExpression; +import org.jetbrains.plugins.groovy.lang.psi.dataFlow.types.TypeInferenceHelper; import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl; import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil; -import org.jetbrains.plugins.groovy.lang.psi.dataFlow.types.TypeInferenceHelper; /** * @author Maxim.Medvedev @@ -40,6 +41,7 @@ public abstract class GrThisSuperReferenceExpressionBase extends GrExpressionImp PsiImplUtil.setQualifier(this, newQualifier); } + @NotNull @Override public PsiElement getReferenceNameElement() { return getLastChild(); @@ -52,7 +54,7 @@ public abstract class GrThisSuperReferenceExpressionBase extends GrExpressionImp @Override public TextRange getRangeInElement() { - final PsiElement token = findNotNullChildByType(TokenSet.create(GroovyElementTypes.kTHIS, GroovyElementTypes.kSUPER)); + final PsiElement token = findNotNullChildByType(TokenSet.create(GroovyTokenTypes.kTHIS, GroovyTokenTypes.kSUPER)); return TextRange.from(token.getStartOffsetInParent(), token.getTextLength()); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/TypesUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/TypesUtil.java index 1b974232bda8..2ad9ef29c14b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/TypesUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/statements/expressions/TypesUtil.java @@ -52,7 +52,10 @@ import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames; import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil; import org.jetbrains.plugins.groovy.util.LightCacheKey; -import java.util.*; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; import static com.intellij.psi.CommonClassNames.*; import static org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes.*; @@ -716,7 +719,7 @@ public class TypesUtil { } @Nullable - public static PsiClassType createSimilarCollection(PsiType collection, Project project, PsiType... itemType) { + public static PsiClassType createSimilarCollection(@Nullable PsiType collection, Project project, PsiType... itemType) { if (InheritanceUtil.isInheritor(collection, "java.util.SortedSet")) { return createCollection(project, "java.util.SortedSet", itemType); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java index d981a05bb719..23f75e30f470 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java @@ -376,8 +376,17 @@ public class PsiUtil { } } } - } + else if (isThisOrSuperRef(qualifier)) { + //static members may be invoked from this.<...> + final boolean isInStatic = isInStaticContext((GrReferenceExpression)qualifier); + if (isThisReference(qualifier) && isInStatic) { + return member.hasModifierProperty(PsiModifier.STATIC); + } + + return !isStatic || !filterStaticAfterInstanceQualifier || CodeInsightSettings.getInstance().SHOW_STATIC_AFTER_INSTANCE; + } + PsiElement qualifierResolved = ((GrReferenceExpression)qualifier).resolve(); if (qualifierResolved instanceof PsiClass || qualifierResolved instanceof PsiPackage) { //static context if (member instanceof PsiClass) { @@ -412,14 +421,6 @@ public class PsiUtil { return false; } } - else if (qualifier instanceof GrThisReferenceExpression && ((GrThisReferenceExpression)qualifier).getQualifier() == null) { - //static members may be invoked from this.<...> - final boolean isInStatic = isInStaticContext((GrThisReferenceExpression)qualifier); - if (containingClass != null && CommonClassNames.JAVA_LANG_CLASS.equals(containingClass.getQualifiedName())) { - return !filterStaticAfterInstanceQualifier || !member.hasModifierProperty(PsiModifier.STATIC) || CodeInsightSettings.getInstance().SHOW_STATIC_AFTER_INSTANCE; - } - else if (isInStatic) return member.hasModifierProperty(PsiModifier.STATIC); - } //instance context if (member instanceof PsiClass) { @@ -517,24 +518,31 @@ public class PsiUtil { } public static boolean isInStaticContext(GrQualifiedReference refExpression) { - return isInStaticContext(refExpression, null); + PsiClass targetClass = null; + if (isThisReference(refExpression) && refExpression.getQualifier() != null) { + targetClass = (PsiClass)((GrReferenceExpression)refExpression.getQualifier()).resolve(); + } + return isInStaticContext(refExpression, targetClass); } public static boolean isInStaticContext(GrQualifiedReference refExpression, @Nullable PsiClass targetClass) { - if (refExpression.getQualifier() != null) { - PsiElement qualifier = refExpression.getQualifier(); - if (qualifier instanceof GrReferenceExpression) return ((GrReferenceExpression)qualifier).resolve() instanceof PsiClass; + PsiElement qualifier = refExpression.getQualifier(); + if (qualifier != null && !isThisOrSuperRef(refExpression)) { + return qualifier instanceof GrReferenceExpression && ((GrReferenceExpression)qualifier).resolve() instanceof PsiClass; } - else { - PsiElement run = refExpression; - while (run != null && run != targetClass) { - if (targetClass == null && run instanceof PsiClass) return false; - if (run instanceof PsiModifierListOwner && ((PsiModifierListOwner)run).hasModifierProperty(PsiModifier.STATIC)) return true; - run = run.getParent(); - } + + + if (isSuperReference(refExpression)) return false; + //this reference should be checked as all other refs + + + PsiElement run = refExpression; + while (run != null && run != targetClass) { + if (targetClass == null && run instanceof PsiClass) return false; + if (run instanceof PsiModifierListOwner && ((PsiModifierListOwner)run).hasModifierProperty(PsiModifier.STATIC)) return true; + run = run.getParent(); } return false; - } public static Iterable iterateSupers(final @NotNull PsiClass psiClass, final boolean includeSelf) { @@ -661,7 +669,7 @@ public class PsiUtil { return true; } - if ((expr instanceof GrThisReferenceExpression || expr instanceof GrSuperReferenceExpression) && + if ((isThisOrSuperRef(expr)) && GroovyConfigUtils.getInstance().isVersionAtLeast(expr, GroovyConfigUtils.GROOVY1_8)) { return true; } @@ -864,7 +872,7 @@ public class PsiUtil { public static boolean hasEnclosingInstanceInScope(@NotNull PsiClass clazz, @Nullable PsiElement scope, boolean isSuperClassAccepted) { PsiElement place = scope; - while (place != null && place != clazz && !(place instanceof PsiFile)) { + while (place != null && place != clazz && !(place instanceof PsiFile && place.isPhysical())) { if (place instanceof PsiClass) { if (isSuperClassAccepted) { if (InheritanceUtil.isInheritorOrSelf((PsiClass)place, clazz, true)) return true; @@ -874,8 +882,9 @@ public class PsiUtil { } } if (place instanceof PsiModifierListOwner && ((PsiModifierListOwner)place).hasModifierProperty(PsiModifier.STATIC)) return false; - place = place.getParent(); + place = place.getContext(); } + if (clazz instanceof GroovyScriptClass) return place == clazz.getContainingFile(); return place == clazz; } @@ -951,7 +960,7 @@ public class PsiUtil { public static boolean isMethodUsage(PsiElement element) { if (element instanceof GrEnumConstant) return true; - if (!(element instanceof GrReferenceElement || element instanceof GrThisSuperReferenceExpression)) return false; + if (!(element instanceof GrReferenceElement)) return false; PsiElement parent = element.getParent(); if (parent instanceof GrCall) { return true; @@ -1184,7 +1193,7 @@ public class PsiUtil { return null; } - + @Nullable public static GrCall getCallByNamedParameter(GrNamedArgument namedArgument) { PsiElement parent = namedArgument.getParent(); @@ -1282,7 +1291,7 @@ public class PsiUtil { @NotNull public static ResolveResult getAccessObjectClass(GrExpression expression) { - if (expression instanceof GrSuperReferenceExpression || expression instanceof GrThisReferenceExpression) return GroovyResolveResult.EMPTY_RESULT; + if (isThisOrSuperRef(expression)) return GroovyResolveResult.EMPTY_RESULT; PsiType type = expression.getType(); if (type instanceof PsiClassType) { return ((PsiClassType)type).resolveGenerics(); @@ -1373,4 +1382,60 @@ public class PsiUtil { if (type instanceof PsiArrayType) return ((PsiArrayType)type).getComponentType(); return com.intellij.psi.util.PsiUtil.extractIterableTypeParameter(type, true); } + + public static boolean isThisReference(@Nullable PsiElement expression) { + if (!(expression instanceof GrReferenceExpression)) return false; + GrReferenceExpression ref = (GrReferenceExpression)expression; + + PsiElement nameElement = ref.getReferenceNameElement(); + if (nameElement == null) return false; + + IElementType type = nameElement.getNode().getElementType(); + if (type != GroovyTokenTypes.kTHIS) return false; + + GrExpression qualifier = ref.getQualifier(); + if (qualifier == null) { + return true; + } + else { + PsiElement resolved = ref.resolve(); + return resolved instanceof PsiClass && hasEnclosingInstanceInScope((PsiClass)resolved, ref, false); + } + } + + public static boolean isSuperReference(@Nullable PsiElement expression) { + if (!(expression instanceof GrReferenceExpression)) return false; + GrReferenceExpression ref = (GrReferenceExpression)expression; + + PsiElement nameElement = ref.getReferenceNameElement(); + if (nameElement == null) return false; + + IElementType type = nameElement.getNode().getElementType(); + if (type != GroovyTokenTypes.kSUPER) return false; + + GrExpression qualifier = ref.getQualifier(); + if (qualifier == null) { + return true; + } + else { + PsiElement resolved = ref.resolve(); + return resolved instanceof PsiClass && hasEnclosingInstanceInScope(((PsiClass)resolved), ref, true); + } + } + + public static boolean isThisOrSuperRef(@Nullable PsiElement qualifier) { + return qualifier instanceof GrReferenceExpression && (isThisReference(qualifier) || isSuperReference(qualifier)); + } + + public static boolean isInstanceThisRef(GrExpression qualifier) { + if (isThisReference(qualifier)) { + GrReferenceExpression ref = (GrReferenceExpression)qualifier; + + PsiElement resolved = ref.resolve(); + if (resolved == null) return false; + + return hasEnclosingInstanceInScope((PsiClass)resolved, qualifier, false); + } + return false; + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java index eaa5f579cbf1..deb5acee0861 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/ResolveUtil.java @@ -49,7 +49,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlo import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisSuperReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrCallExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrAnonymousClassDefinition; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition; @@ -575,7 +574,6 @@ public class ResolveUtil { public static boolean mayBeKeyOfMap(GrReferenceExpression ref) { final GrExpression qualifier = getSelfOrWithQualifier(ref); if (qualifier == null) return false; - if (qualifier instanceof GrThisSuperReferenceExpression) return false; if (qualifier instanceof GrReferenceExpression && ((GrReferenceExpression)qualifier).resolve() instanceof PsiClass) return false; return InheritanceUtil.isInheritor(qualifier.getType(), CommonClassNames.JAVA_UTIL_MAP); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyChangeContextUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyChangeContextUtil.java index 712bf183f0aa..83aeabdf0ea6 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyChangeContextUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyChangeContextUtil.java @@ -24,8 +24,8 @@ import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod; +import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; /** * @author Maxim.Medvedev @@ -45,8 +45,8 @@ public class GroovyChangeContextUtil { public static void encodeContextInfo(PsiElement element, PsiElement scope) { if (!(element instanceof GroovyPsiElement)) return; - if (element instanceof GrThisReferenceExpression) { - GrThisReferenceExpression thisExpr = (GrThisReferenceExpression)element; + if (PsiUtil.isThisReference(element)) { + GrReferenceExpression thisExpr = (GrReferenceExpression)element; final PsiClass containingClass = PsiTreeUtil.getParentOfType(thisExpr, PsiClass.class); element.putCopyableUserData(KEY_ENCODED, KEY_ENCODED); thisExpr.putCopyableUserData(QUALIFIER_CLASS_KEY, containingClass); @@ -94,7 +94,7 @@ public class GroovyChangeContextUtil { if (element.getCopyableUserData(KEY_ENCODED) != null) { element.putCopyableUserData(KEY_ENCODED, null); final PsiManager manager = element.getManager(); - if (element instanceof GrThisReferenceExpression) { + if (PsiUtil.isThisReference(element)) { final PsiClass thisQualClass = element.getCopyableUserData(QUALIFIER_CLASS_KEY); element.putCopyableUserData(QUALIFIER_CLASS_KEY, null); if (thisAccessExpr != null && !manager.areElementsEquivalent(thisClass, thisQualClass)) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyNameSuggestionUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyNameSuggestionUtil.java index c23bd1bdf594..19dbd1bc2928 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyNameSuggestionUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyNameSuggestionUtil.java @@ -28,10 +28,9 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrSuperReferenceExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression; +import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; import java.util.ArrayList; import java.util.Collections; @@ -94,13 +93,13 @@ public class GroovyNameSuggestionUtil { } private static void generateNameByExpr(GrExpression expr, Set possibleNames, NameValidator validator, boolean forStaticVariable) { - if (expr instanceof GrThisReferenceExpression) { - possibleNames.add(validator.validateName("thisInstance", true)); - } - if (expr instanceof GrSuperReferenceExpression) { - possibleNames.add(validator.validateName("superInstance", true)); - } if (expr instanceof GrReferenceExpression && ((GrReferenceExpression) expr).getName() != null) { + if (PsiUtil.isThisReference(expr)) { + possibleNames.add(validator.validateName("thisInstance", true)); + } + if (PsiUtil.isSuperReference(expr)) { + possibleNames.add(validator.validateName("superInstance", true)); + } GrReferenceExpression refExpr = (GrReferenceExpression) expr; String name = refExpr.getName(); if (name != null && name.toUpperCase().equals(name)) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringUtil.java index b83555bf9b3f..512a239f81f6 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/GroovyRefactoringUtil.java @@ -196,7 +196,7 @@ public abstract class GroovyRefactoringUtil { }); } - public static boolean isLocalVariable(PsiElement variable) { + public static boolean isLocalVariable(@Nullable PsiElement variable) { return variable instanceof GrVariable && !(variable instanceof GrField || variable instanceof GrParameter); } @@ -460,7 +460,7 @@ public abstract class GroovyRefactoringUtil { int result = EXPR_COPY_SAFE; if (element == null) return result; - if (element instanceof GrThisReferenceExpression || element instanceof GrSuperReferenceExpression || element instanceof GrNamedElement) { + if (element instanceof GrNamedElement) { return EXPR_COPY_SAFE; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureUsageProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureUsageProcessor.java index fe4469a9f38f..657902baa56d 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureUsageProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/changeSignature/GrChangeSignatureUsageProcessor.java @@ -449,7 +449,7 @@ public class GrChangeSignatureUsageProcessor implements ChangeSignatureUsageProc GrConstructorInvocation invocation = GroovyPsiElementFactory.getInstance(constructor.getProject()).createConstructorInvocation("super()"); invocation = (GrConstructorInvocation)block.addStatementBefore(invocation, getFirstStatement(block)); - processMethodUsage(invocation.getThisOrSuperKeyword(), changeInfo, + processMethodUsage(invocation.getInvokedExpression(), changeInfo, changeInfo.isParameterSetOrOrderChanged() || changeInfo.isParameterNamesChanged(), changeInfo.isExceptionSetChanged(), GrClosureSignatureUtil.ArgInfo.empty_array(), substitutor); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerator.java index d4de2c42e577..6badf51b5d3b 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/CodeBlockGenerator.java @@ -44,7 +44,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrForInClaus import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrTraditionalForClause; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrApplicationStatement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisSuperReferenceExpression; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition; import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod; @@ -163,7 +163,7 @@ public class CodeBlockGenerator extends Generator { GenerationUtil.writeStatement(builder, context, invocation, new StatementWriter() { @Override public void writeStatement(StringBuilder builder, ExpressionContext context) { - final GrThisSuperReferenceExpression thisOrSuperKeyword = invocation.getThisOrSuperKeyword(); + final GrReferenceExpression thisOrSuperKeyword = invocation.getInvokedExpression(); final GrArgumentList argumentList = invocation.getArgumentList(); final GroovyResolveResult resolveResult = invocation.advancedResolve(); if (thisOrSuperKeyword.getQualifier() == null) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionGenerator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionGenerator.java index 9fff2760ea02..621dcf433952 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionGenerator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/convertToJava/ExpressionGenerator.java @@ -59,6 +59,7 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.GrLiteralClassType; import org.jetbrains.plugins.groovy.lang.psi.impl.GrRangeType; import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil; +import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrReferenceResolveUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil; import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.ClosureSyntheticParameter; import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightLocalVariable; @@ -436,13 +437,16 @@ public class ExpressionGenerator extends Generator { else if (resolved == null || resolved instanceof GrLightLocalVariable) { //write unresolved reference assignment via setter GroovyObject.setProperty(String name, Object value) final GrExpression qualifier = ((GrReferenceExpression)realLValue).getQualifier(); - final PsiType type = qualifier != null ? qualifier.getType() : factory.createExpressionFromText("this", expression).getType(); + final PsiType type = GrReferenceResolveUtil.getQualifierType((GrReferenceExpression)realLValue); - final GrExpression[] args = new GrExpression[2]; - args[0] = factory.createExpressionFromText("\"" + ((GrReferenceExpression)realLValue).getReferenceName() + "\""); - args[1] = getRValue(expression); - final PsiElement method = PsiImplUtil - .extractUniqueElement(ResolveUtil.getMethodCandidates(type, "setProperty", expression, args[0].getType(), args[1].getType())); + final GrExpression[] args = { + factory.createExpressionFromText("\"" + ((GrReferenceExpression)realLValue).getReferenceName() + "\""), + getRValue(expression) + }; + GroovyResolveResult[] candidates = type != null + ? ResolveUtil.getMethodCandidates(type, "setProperty", expression, args[0].getType(), args[1].getType()) + : GroovyResolveResult.EMPTY_ARRAY; + final PsiElement method = PsiImplUtil.extractUniqueElement(candidates); if (method instanceof PsiMethod) { writeAssignmentWithSetter(qualifier, (PsiMethod)method, args, GrNamedArgument.EMPTY_ARRAY, EMPTY_ARRAY, PsiSubstitutor.EMPTY, @@ -870,6 +874,16 @@ public class ExpressionGenerator extends Generator { @Override public void visitReferenceExpression(GrReferenceExpression referenceExpression) { + if (PsiUtil.isThisOrSuperRef(referenceExpression)) { + GrExpression qualifier = referenceExpression.getQualifier(); + if (!context.isInAnonymousContext() && qualifier != null) { + qualifier.accept(this); + } + builder.append(referenceExpression.getReferenceName()); + return; + } + + final GrExpression qualifier = referenceExpression.getQualifier(); final GroovyResolveResult resolveResult = referenceExpression.advancedResolve(); final PsiElement resolved = resolveResult.getElement(); @@ -967,7 +981,19 @@ public class ExpressionGenerator extends Generator { builder.append(refName); } else { - builder.append("getProperty(\"").append(refName).append("\")"); + PsiType stringType = PsiType.getJavaLangString(referenceExpression.getManager(), referenceExpression.getResolveScope()); + PsiType qualifierType = GrReferenceResolveUtil.getQualifierType(referenceExpression); + GroovyResolveResult[] candidates = qualifierType != null + ? ResolveUtil.getMethodCandidates(qualifierType, "getProperty", referenceExpression, + stringType) + : GroovyResolveResult.EMPTY_ARRAY; + final PsiElement method = PsiImplUtil.extractUniqueElement(candidates); + if (method != null) { + builder.append("getProperty(\"").append(refName).append("\")"); + } + else { + builder.append(refName); + } } } else { @@ -1010,15 +1036,6 @@ public class ExpressionGenerator extends Generator { return name; } - @Override - public void visitThisSuperReferenceExpression(GrThisSuperReferenceExpression expr) { - GrReferenceExpression qualifier = expr.getQualifier(); - if (!context.isInAnonymousContext() && qualifier != null) { - qualifier.accept(this); - } - builder.append(expr.getReferenceName()); - } - @Override public void visitCastExpression(GrTypeCastExpression typeCastExpression) { final GrTypeElement typeElement = typeCastExpression.getCastTypeElement(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/closure/ExtractClosureFromMethodProcessor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/closure/ExtractClosureFromMethodProcessor.java index 3627c3b52566..6f6c08dbd4f0 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/closure/ExtractClosureFromMethodProcessor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/extract/closure/ExtractClosureFromMethodProcessor.java @@ -47,10 +47,10 @@ import org.jetbrains.plugins.groovy.lang.psi.api.util.GrStatementOwner; import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringBundle; import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil; import org.jetbrains.plugins.groovy.refactoring.extract.ExtractUtil; -import org.jetbrains.plugins.groovy.refactoring.introduce.parameter.AnySupers; import org.jetbrains.plugins.groovy.refactoring.introduce.parameter.FieldConflictsResolver; import org.jetbrains.plugins.groovy.refactoring.introduce.parameter.GrExpressionWrapper; import org.jetbrains.plugins.groovy.refactoring.introduce.parameter.GrIntroduceParameterSettings; +import org.jetbrains.plugins.groovy.refactoring.util.AnySupers; import java.util.ArrayList; import java.util.Collection; @@ -96,7 +96,7 @@ public class ExtractClosureFromMethodProcessor extends ExtractClosureProcessorBa for (GrStatement statement : statements) { statement.accept(anySupers); } - if (anySupers.isResult()) { + if (anySupers.containsSupers()) { for (UsageInfo usageInfo : usagesIn) { if (!(usageInfo.getElement() instanceof PsiMethod) && !(usageInfo instanceof InternalUsageInfo)) { if (!PsiTreeUtil.isAncestor(myMethod.getContainingClass(), usageInfo.getElement(), false)) { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/inline/GroovyMethodInliner.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/inline/GroovyMethodInliner.java index c2811059540d..3f88bf883447 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/inline/GroovyMethodInliner.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/inline/GroovyMethodInliner.java @@ -23,7 +23,6 @@ import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.wm.WindowManager; import com.intellij.psi.*; @@ -40,7 +39,6 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils; import org.jetbrains.plugins.groovy.lang.GrReferenceAdjuster; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory; -import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable; @@ -51,7 +49,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrReturnStatement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrSuperReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrCallExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; @@ -63,6 +60,7 @@ import org.jetbrains.plugins.groovy.refactoring.GroovyNameSuggestionUtil; import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringBundle; import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil; import org.jetbrains.plugins.groovy.refactoring.NameValidator; +import org.jetbrains.plugins.groovy.refactoring.util.AnySupers; import java.util.ArrayList; import java.util.Collection; @@ -107,14 +105,9 @@ public class GroovyMethodInliner implements InlineHandler.Inliner { } } } - final Ref hasSuper = new Ref(false); - info.expression.accept(new GroovyRecursiveElementVisitor() { - @Override - public void visitSuperExpression(GrSuperReferenceExpression superExpression) { - hasSuper.set(true); - } - }); - if (hasSuper.get()) { + AnySupers visitor = new AnySupers(); + info.expression.accept(visitor); + if (visitor.containsSupers()) { conflicts.putValue(info.expression, GroovyRefactoringBundle.message("super.reference.is.used")); } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/GrIntroduceHandlerBase.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/GrIntroduceHandlerBase.java index 4e3dc84f7ba1..9a07f2b1eb5e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/GrIntroduceHandlerBase.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/refactoring/introduce/GrIntroduceHandlerBase.java @@ -104,7 +104,7 @@ public abstract class GrIntroduceHandlerBaseo(['']) ''') - def parameters = resolved.parameterList.parameters + assertInstanceOf(resolved, PsiMethod) + def parameters = (resolved as PsiMethod).parameterList.parameters assertEquals 'java.util.List', parameters[0].type.canonicalText } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.groovy index 73dd4fdd2dfa..9581266c5499 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/resolve/TypeInferenceTest.groovy @@ -150,6 +150,8 @@ public class TypeInferenceTest extends GroovyResolveTestCase { public void testMethodCallInvokedOnArrayAccess() { final GrReferenceExpression reference = (GrReferenceExpression)configureByFile("A.groovy"); + assertNotNull(reference) + assertNotNull(reference.type) assertEquals("java.lang.Integer", reference.type.canonicalText); } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceParameter/GrIntroduceParameterTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceParameter/GrIntroduceParameterTest.java index e143c274a388..a5efacf2f4bb 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceParameter/GrIntroduceParameterTest.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/introduceParameter/GrIntroduceParameterTest.java @@ -190,6 +190,10 @@ public class GrIntroduceParameterTest extends LightCodeInsightFixtureTestCase { doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false, "field Test.i is not accessible from method XTest.n(). Value for introduced parameter in that method call will be incorrect."); } + public void testQualifiedThisSubstitution() { + doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false, null); + } + public void testFieldAccess() { doTest(IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, false, false); } diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/rename/RenameTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/rename/RenameTest.groovy index f53ac2d62f2b..bda23832691c 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/rename/RenameTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/refactoring/rename/RenameTest.groovy @@ -616,4 +616,30 @@ class Bar { checkResult("def 'import'() {}") } } + + void testConstructorAndSuper() { + myFixture.with { + configureByText(GroovyFileType.GROOVY_FILE_TYPE, '''\ +class Base { + def Base() {} +} +class Inheritor extends Base { + def Inheritor() { + super() + } +} +''') + renameElementAtCaret('Bassse') + checkResult('''\ +class Bassse { + def Bassse() {} +} +class Inheritor extends Bassse { + def Inheritor() { + super() + } +} +''') + } + } } diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/path/path10.test b/plugins/groovy/testdata/parsing/groovy/expressions/path/path10.test index 995e8b373e89..7f83251eae79 100644 --- a/plugins/groovy/testdata/parsing/groovy/expressions/path/path10.test +++ b/plugins/groovy/testdata/parsing/groovy/expressions/path/path10.test @@ -7,7 +7,7 @@ Groovy script PsiWhiteSpace(' ') Command arguments Reference expression - 'this' reference expression + Reference expression PsiElement(this)('this') PsiElement(.)('.') PsiElement(final)('final') \ No newline at end of file diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/super/qualifiedSuper.test b/plugins/groovy/testdata/parsing/groovy/expressions/super/qualifiedSuper.test index b01bd613902d..19566887571b 100644 --- a/plugins/groovy/testdata/parsing/groovy/expressions/super/qualifiedSuper.test +++ b/plugins/groovy/testdata/parsing/groovy/expressions/super/qualifiedSuper.test @@ -32,7 +32,7 @@ Groovy script PsiWhiteSpace('\n ') Method call Reference expression - 'super' reference expression + Reference expression Reference expression PsiElement(identifier)('X') PsiElement(.)('.') diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/super/super.test b/plugins/groovy/testdata/parsing/groovy/expressions/super/super.test index ee2cbdd35772..d0f8167d0be9 100644 --- a/plugins/groovy/testdata/parsing/groovy/expressions/super/super.test +++ b/plugins/groovy/testdata/parsing/groovy/expressions/super/super.test @@ -32,7 +32,7 @@ Groovy script PsiWhiteSpace('\n ') Method call Reference expression - 'super' reference expression + Reference expression PsiElement(super)('super') PsiElement(.)('.') PsiElement(identifier)('foo') diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/this/qualifiedThis.test b/plugins/groovy/testdata/parsing/groovy/expressions/this/qualifiedThis.test index e163a558b800..65d2f390d8b4 100644 --- a/plugins/groovy/testdata/parsing/groovy/expressions/this/qualifiedThis.test +++ b/plugins/groovy/testdata/parsing/groovy/expressions/this/qualifiedThis.test @@ -32,7 +32,7 @@ Groovy script PsiWhiteSpace('\n ') Method call Reference expression - 'this' reference expression + Reference expression Reference expression PsiElement(identifier)('X') PsiElement(.)('.') diff --git a/plugins/groovy/testdata/parsing/groovy/expressions/this/this.test b/plugins/groovy/testdata/parsing/groovy/expressions/this/this.test index f8596b4da6ff..c784ae1d3506 100644 --- a/plugins/groovy/testdata/parsing/groovy/expressions/this/this.test +++ b/plugins/groovy/testdata/parsing/groovy/expressions/this/this.test @@ -34,7 +34,7 @@ Groovy script PsiWhiteSpace('\n ') Method call Reference expression - 'this' reference expression + Reference expression PsiElement(this)('this') PsiElement(.)('.') PsiElement(identifier)('doo') diff --git a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor1.test b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor1.test index 17b392c66fb5..40a8bf464ef4 100644 --- a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor1.test +++ b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor1.test @@ -32,7 +32,7 @@ Groovy script PsiElement({)('{') PsiWhiteSpace('\n ') Constructor invocation - 'this' reference expression + Reference expression PsiElement(this)('this') PsiWhiteSpace(' ') Arguments diff --git a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor13.test b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor13.test index b263c2526606..5a5ad21508a2 100644 --- a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor13.test +++ b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor13.test @@ -56,7 +56,7 @@ Groovy script PsiElement(;)(';') PsiWhiteSpace(' ') Method call - 'super' reference expression + Reference expression PsiElement(super)('super') PsiWhiteSpace(' ') Arguments diff --git a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor14.test b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor14.test index fb85bb8aaaca..4e93519e609a 100644 --- a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor14.test +++ b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor14.test @@ -53,7 +53,7 @@ Groovy script PsiWhiteSpace('\n ') Assignment expression Reference expression - 'this' reference expression + Reference expression PsiElement(this)('this') PsiElement(.)('.') PsiElement(identifier)('value') @@ -90,7 +90,7 @@ Groovy script PsiElement(()('(') Additive expression Reference expression - 'this' reference expression + Reference expression PsiElement(this)('this') PsiElement(.)('.') PsiElement(identifier)('value') diff --git a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor2.test b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor2.test index 0dccf897942e..8957bb76721c 100644 --- a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor2.test +++ b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor2.test @@ -34,7 +34,7 @@ Groovy script PsiElement({)('{') PsiWhiteSpace('\n ') Constructor invocation - 'super' reference expression + Reference expression PsiElement(super)('super') Arguments PsiElement(()('(') diff --git a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor3.test b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor3.test index 3a7d3dfa2214..51ff31e0496c 100644 --- a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor3.test +++ b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor3.test @@ -32,7 +32,7 @@ Groovy script PsiElement({)('{') PsiWhiteSpace('\n ') Constructor invocation - 'this' reference expression + Reference expression PsiElement(this)('this') Arguments PsiElement(()('(') diff --git a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor4.test b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor4.test index 0dbc2d8ea427..3a81eb30921d 100644 --- a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor4.test +++ b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor4.test @@ -63,7 +63,7 @@ Groovy script Open block PsiElement({)('{') Method call - 'this' reference expression + Reference expression PsiElement(this)('this') Arguments PsiElement(()('(') diff --git a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor5.test b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor5.test index 72e3ca82f323..6b71774722f6 100644 --- a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor5.test +++ b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor5.test @@ -39,7 +39,7 @@ Groovy script PsiElement({)('{') PsiWhiteSpace('\n ') Constructor invocation - 'this' reference expression + Reference expression PsiElement(this)('this') PsiWhiteSpace(' ') Arguments diff --git a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor6.test b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor6.test index c711c17da9ca..36a2c2dc5518 100644 --- a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor6.test +++ b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor6.test @@ -33,7 +33,7 @@ Groovy script PsiElement({)('{') PsiWhiteSpace('\n ') Constructor invocation - 'this' reference expression + Reference expression PsiElement(this)('this') Arguments PsiElement(()('(') diff --git a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor8.test b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor8.test index 8ecd734e6fb3..9fd9b58e4f3a 100644 --- a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor8.test +++ b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor8.test @@ -39,7 +39,7 @@ Groovy script PsiElement({)('{') PsiWhiteSpace('\n ') Constructor invocation - 'this' reference expression + Reference expression PsiElement(this)('this') PsiWhiteSpace(' ') Arguments diff --git a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor9.test b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor9.test index eea22f6ef80a..db38417f528c 100644 --- a/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor9.test +++ b/plugins/groovy/testdata/parsing/groovy/statements/typedef/constructors/constructor9.test @@ -43,7 +43,7 @@ Groovy script PsiElement({)('{') PsiWhiteSpace('\n ') Constructor invocation - 'this' reference expression + Reference expression PsiElement(this)('this') PsiWhiteSpace(' ') Arguments diff --git a/plugins/groovy/testdata/parsing/groovy/statements/typedef/interfaces/errors/interfaceerr1.test b/plugins/groovy/testdata/parsing/groovy/statements/typedef/interfaces/errors/interfaceerr1.test index f551a5148732..f1537c42f185 100644 --- a/plugins/groovy/testdata/parsing/groovy/statements/typedef/interfaces/errors/interfaceerr1.test +++ b/plugins/groovy/testdata/parsing/groovy/statements/typedef/interfaces/errors/interfaceerr1.test @@ -52,7 +52,7 @@ Groovy script PsiElement({)('{') PsiWhiteSpace('\n ') Constructor invocation - 'this' reference expression + Reference expression PsiElement(this)('this') Arguments PsiElement(()('(') diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/constructor.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/constructor.java index 31fe43caeb6c..28fa5574f185 100644 --- a/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/constructor.java +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/constructor.java @@ -1,5 +1,5 @@ public class Base extends groovy.lang.GroovyObjectSupport implements groovy.lang.GroovyObject { -public Base(java.lang.Object a) { +public Base(java.lang.Integer a) { } } public class Inheritor extends Base implements groovy.lang.GroovyObject { diff --git a/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/dynamicPropertiesAccess.java b/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/dynamicPropertiesAccess.java index 34b1830d6ced..35e9c5a95f14 100644 --- a/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/dynamicPropertiesAccess.java +++ b/plugins/groovy/testdata/refactoring/convertGroovyToJava/file/dynamicPropertiesAccess.java @@ -6,7 +6,7 @@ java.lang.String s = "a"; s.bar = 4; org.codehaus.groovy.runtime.DefaultGroovyMethods.print(this, s.bar = 5); org.codehaus.groovy.runtime.DefaultGroovyMethods.print(this, getProperty("bar")); -org.codehaus.groovy.runtime.DefaultGroovyMethods.print(this, s.getProperty("bar")); +org.codehaus.groovy.runtime.DefaultGroovyMethods.print(this, s.bar); } private static Value setProperty0(groovy.lang.GroovyObjectSupport propOwner, java.lang.String property, Value newValue) { diff --git a/plugins/groovy/testdata/refactoring/introduceParameterGroovy/qualifiedThisSubstitution/QualifiedThisSubstitutionAfter.groovy b/plugins/groovy/testdata/refactoring/introduceParameterGroovy/qualifiedThisSubstitution/QualifiedThisSubstitutionAfter.groovy new file mode 100644 index 000000000000..01a70f6cbc26 --- /dev/null +++ b/plugins/groovy/testdata/refactoring/introduceParameterGroovy/qualifiedThisSubstitution/QualifiedThisSubstitutionAfter.groovy @@ -0,0 +1,2 @@ +final Upper.Foo foo = new Upper.Foo() +foo.abr(foo) \ No newline at end of file diff --git a/plugins/groovy/testdata/refactoring/introduceParameterGroovy/qualifiedThisSubstitution/QualifiedThisSubstitutionBefore.groovy b/plugins/groovy/testdata/refactoring/introduceParameterGroovy/qualifiedThisSubstitution/QualifiedThisSubstitutionBefore.groovy new file mode 100644 index 000000000000..8a9bb09997b0 --- /dev/null +++ b/plugins/groovy/testdata/refactoring/introduceParameterGroovy/qualifiedThisSubstitution/QualifiedThisSubstitutionBefore.groovy @@ -0,0 +1 @@ +new Upper.Foo().abr() \ No newline at end of file diff --git a/plugins/groovy/testdata/refactoring/introduceParameterGroovy/qualifiedThisSubstitution/QualifiedThisSubstitutionMyClass.groovy b/plugins/groovy/testdata/refactoring/introduceParameterGroovy/qualifiedThisSubstitution/QualifiedThisSubstitutionMyClass.groovy new file mode 100644 index 000000000000..bc1bb69d6b10 --- /dev/null +++ b/plugins/groovy/testdata/refactoring/introduceParameterGroovy/qualifiedThisSubstitution/QualifiedThisSubstitutionMyClass.groovy @@ -0,0 +1,9 @@ +class Upper { + class Foo { + def x = 4 + + def abr() { + print Foo.this.x + } + } +} \ No newline at end of file From f659470d6d860ceeefd9023cd061d80c7bcc7cfa Mon Sep 17 00:00:00 2001 From: Anton Makeev Date: Tue, 23 Oct 2012 16:18:51 +0200 Subject: [PATCH 15/15] AppCode: XcodeMetaData per-configuration --- .../testFramework/UsefulTestCase.java | 38 ++++++++++++++++++- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java index e52fb71106bd..5898d1ea879f 100644 --- a/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java +++ b/platform/testFramework/src/com/intellij/testFramework/UsefulTestCase.java @@ -378,18 +378,52 @@ public abstract class UsefulTestCase extends TestCase { } public static void assertSameElements(Collection collection, Collection expected) { + assertSameElements(null, collection, expected); + } + + public static void assertSameElements(String message, Collection collection, Collection expected) { assertNotNull(collection); assertNotNull(expected); if (collection.size() != expected.size() || !new HashSet(expected).equals(new HashSet(collection))) { - Assert.assertEquals(toString(expected, "\n"), toString(collection, "\n")); - Assert.assertEquals(new HashSet(expected), new HashSet(collection)); + Assert.assertEquals(message, toString(expected, "\n"), toString(collection, "\n")); + Assert.assertEquals(message, new HashSet(expected), new HashSet(collection)); } } + + public void assertContainsOrdered(Collection collection, T... expected) { + assertContainsOrdered(collection, Arrays.asList(expected)); + } + + public void assertContainsOrdered(Collection collection, Collection expected) { + ArrayList copy = new ArrayList(collection); + copy.retainAll(expected); + assertOrderedEquals(toString(collection), copy, expected); + } + + public void assertContainsElements(Collection collection, T... expected) { + assertContainsElements(collection, Arrays.asList(expected)); + } + + public void assertContainsElements(Collection collection, Collection expected) { + ArrayList copy = new ArrayList(collection); + copy.retainAll(expected); + assertSameElements(toString(collection), copy, expected); + } public static String toString(Object[] collection, String separator) { return toString(Arrays.asList(collection), separator); } + public void assertDoesntContain(Collection collection, T... notExpected) { + assertDoesntContain(collection, Arrays.asList(notExpected)); + } + + public void assertDoesntContain(Collection collection, Collection notExpected) { + ArrayList copy = new ArrayList(collection); + copy.retainAll(notExpected); + assertEmpty(copy); + } + public static String toString(Collection collection, String separator) { List list = ContainerUtil.map2List(collection, new Function() { @Override