mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
+41
-15
@@ -1,18 +1,4 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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.
|
||||
*/
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.codeInsight.daemon.impl.quickfix;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightUtilCore;
|
||||
@@ -22,6 +8,7 @@ import com.intellij.codeInsight.intention.impl.BaseIntentionAction;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupElementBuilder;
|
||||
import com.intellij.codeInsight.template.*;
|
||||
import com.intellij.codeInsight.template.impl.TemplateState;
|
||||
import com.intellij.ide.DataManager;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -39,6 +26,7 @@ import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.refactoring.JavaRefactoringSettings;
|
||||
import com.intellij.refactoring.introduceVariable.IntroduceVariableBase;
|
||||
import com.intellij.refactoring.util.RefactoringChangeUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.siyeh.ig.psiutils.EquivalenceChecker;
|
||||
@@ -221,6 +209,44 @@ public class CreateLocalVarFromInstanceofAction extends BaseIntentionAction {
|
||||
newEditor.getDocument().deleteString(range.getStartOffset(), range.getEndOffset());
|
||||
|
||||
CreateFromUsageBaseFix.startTemplate(newEditor, template, project, new TemplateEditingAdapter() {
|
||||
|
||||
@Override
|
||||
public void beforeTemplateFinished(@NotNull TemplateState state, Template template) {
|
||||
final TextResult value = state.getVariableValue("");
|
||||
assert value != null;
|
||||
|
||||
final PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(project).getResolveHelper();
|
||||
final PsiVariable target = resolveHelper.resolveAccessibleReferencedVariable(value.getText(), instanceOfExpression);
|
||||
if (target instanceof PsiField) {
|
||||
final PsiField field = (PsiField)target;
|
||||
final CaretModel caretModel = editor.getCaretModel();
|
||||
final PsiElement elementAt = file.findElementAt(caretModel.getOffset());
|
||||
final PsiDeclarationStatement declarationStatement = PsiTreeUtil.getParentOfType(elementAt, PsiDeclarationStatement.class);
|
||||
if (declarationStatement != null) {
|
||||
final PsiLocalVariable variable = (PsiLocalVariable)declarationStatement.getDeclaredElements()[0];
|
||||
final PsiExpression initializer = variable.getInitializer();
|
||||
assert initializer != null;
|
||||
ApplicationManager.getApplication().runWriteAction(() -> {
|
||||
initializer.accept(new JavaRecursiveElementVisitor() {
|
||||
@Override
|
||||
public void visitReferenceExpression(PsiReferenceExpression expression) {
|
||||
final PsiExpression qualifierExpression = expression.getQualifierExpression();
|
||||
if (qualifierExpression != null) {
|
||||
qualifierExpression.accept(this);
|
||||
}
|
||||
else if (expression.resolve() == variable) {
|
||||
RefactoringChangeUtil.qualifyReference(expression, field, field.hasModifierProperty(PsiModifier.STATIC)
|
||||
? field.getContainingClass()
|
||||
: null);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.getDocument());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void templateFinished(@NotNull Template template, boolean brokenOff) {
|
||||
ApplicationManager.getApplication().runWriteAction(() -> {
|
||||
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
// "Insert '(String)x' declaration" "true"
|
||||
|
||||
class C {
|
||||
Object x = new Object();
|
||||
|
||||
void x() {
|
||||
if (x instanceof String) {
|
||||
String x = (String) this.x;
|
||||
<caret>
|
||||
}
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
// "Insert '(String)x' declaration" "true"
|
||||
|
||||
class C {
|
||||
Object x = new Object();
|
||||
|
||||
void x() {
|
||||
if (x insta<caret>nceof String) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-4
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.structuralsearch.impl.matcher.compiler;
|
||||
|
||||
import com.intellij.dupLocator.iterators.NodeIterator;
|
||||
@@ -45,7 +45,7 @@ public class JavaCompilingVisitor extends JavaRecursiveElementWalkingVisitor {
|
||||
PsiKeyword.THROWS, PsiKeyword.EXTENDS, PsiKeyword.IMPLEMENTS);
|
||||
|
||||
public JavaCompilingVisitor(GlobalCompilingVisitor compilingVisitor) {
|
||||
this.myCompilingVisitor = compilingVisitor;
|
||||
myCompilingVisitor = compilingVisitor;
|
||||
}
|
||||
|
||||
public void compile(PsiElement[] topLevelElements) {
|
||||
@@ -94,6 +94,7 @@ public class JavaCompilingVisitor extends JavaRecursiveElementWalkingVisitor {
|
||||
|
||||
@Override
|
||||
public void visitCatchSection(PsiCatchSection section) {
|
||||
// check parameter first and skip catch section if count is zero
|
||||
final PsiParameter parameter = section.getParameter();
|
||||
if (parameter != null && !handleWord(parameter.getName(), CODE, myCompilingVisitor.getContext())) return;
|
||||
super.visitCatchSection(section);
|
||||
@@ -138,7 +139,7 @@ public class JavaCompilingVisitor extends JavaRecursiveElementWalkingVisitor {
|
||||
}
|
||||
else if (element instanceof PsiKeyword) {
|
||||
final String keyword = element.getText();
|
||||
if (!excludedKeywords.contains(keyword)) {
|
||||
if (!excludedKeywords.contains(keyword) || element.getParent() instanceof PsiExpression) {
|
||||
GlobalCompilingVisitor.addFilesToSearchForGivenWord(keyword, true, CODE, myCompilingVisitor.getContext());
|
||||
}
|
||||
}
|
||||
@@ -146,7 +147,7 @@ public class JavaCompilingVisitor extends JavaRecursiveElementWalkingVisitor {
|
||||
|
||||
@Override
|
||||
public List<String> getDescendantsOf(String className, boolean includeSelf, Project project) {
|
||||
SmartList<String> result = new SmartList<>();
|
||||
final SmartList<String> result = new SmartList<>();
|
||||
|
||||
// use project and libraries scope, because super class may be outside the scope of the search
|
||||
final GlobalSearchScope projectAndLibraries = ProjectScope.getAllScope(project);
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.util.text.TrigramBuilder;
|
||||
import com.intellij.openapi.vfs.*;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.impl.cache.CacheManager;
|
||||
@@ -443,8 +444,8 @@ class FindInProjectTask {
|
||||
private Pair.NonNull<PsiFile, VirtualFile> findFile(@NotNull final VirtualFile virtualFile) {
|
||||
PsiFile psiFile = myPsiManager.findFile(virtualFile);
|
||||
if (psiFile != null) {
|
||||
PsiFile sourceFile = (PsiFile)psiFile.getNavigationElement();
|
||||
if (sourceFile != null) psiFile = sourceFile;
|
||||
PsiElement sourceFile = psiFile.getNavigationElement();
|
||||
if (sourceFile instanceof PsiFile) psiFile = (PsiFile)sourceFile;
|
||||
if (psiFile.getFileType().isBinary()) {
|
||||
psiFile = null;
|
||||
}
|
||||
|
||||
@@ -42,5 +42,5 @@ object LafIconLookup {
|
||||
fun getDisabledIcon(name: String): Icon = getIcon(name, enabled = false)
|
||||
|
||||
@JvmStatic
|
||||
fun getSelectedIcon(name: String): Icon = getIcon(name, selected = true)
|
||||
fun getSelectedIcon(name: String): Icon = findIcon(name, selected = true) ?: getIcon(name)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.diagnostic;
|
||||
|
||||
import com.intellij.errorreport.error.InternalEAPException;
|
||||
@@ -139,7 +139,7 @@ class ITNProxy {
|
||||
@Nullable String password,
|
||||
@NotNull ErrorBean error,
|
||||
@NotNull IntConsumer onSuccess,
|
||||
@NotNull Consumer<? super Exception> onError) {
|
||||
@NotNull Consumer<Exception> onError) {
|
||||
if (StringUtil.isEmptyOrSpaces(login)) {
|
||||
login = DEFAULT_USER;
|
||||
password = DEFAULT_PASS;
|
||||
@@ -175,6 +175,9 @@ class ITNProxy {
|
||||
|
||||
HttpURLConnection connection = post(new URL(NEW_THREAD_POST_URL), createRequest(login, password, error));
|
||||
int responseCode = connection.getResponseCode();
|
||||
if (responseCode == HttpURLConnection.HTTP_BAD_REQUEST && StringUtil.isEmpty(password)) {
|
||||
throw new NoSuchEAPUserException(login);
|
||||
}
|
||||
if (responseCode != HttpURLConnection.HTTP_OK) {
|
||||
throw new InternalEAPException(DiagnosticBundle.message("error.http.result.code", responseCode));
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.diagnostic
|
||||
|
||||
import com.intellij.CommonBundle
|
||||
import com.intellij.credentialStore.Credentials
|
||||
import com.intellij.credentialStore.hasOnlyUserName
|
||||
import com.intellij.credentialStore.isFulfilled
|
||||
import com.intellij.diagnostic.ITNProxy.ErrorBean
|
||||
import com.intellij.errorreport.error.InternalEAPException
|
||||
import com.intellij.errorreport.error.NoSuchEAPUserException
|
||||
import com.intellij.errorreport.error.UpdateAvailableException
|
||||
import com.intellij.ide.DataManager
|
||||
@@ -61,7 +61,7 @@ open class ITNReporter : ErrorReportSubmitter() {
|
||||
|
||||
val project = CommonDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(parentComponent))
|
||||
|
||||
return submit(errorBean, parentComponent, consumer, project)
|
||||
return submit(errorBean, consumer, parentComponent, project)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,20 +70,20 @@ open class ITNReporter : ErrorReportSubmitter() {
|
||||
open fun showErrorInRelease(event: IdeaLoggingEvent): Boolean = false
|
||||
}
|
||||
|
||||
private fun submit(errorBean: ErrorBean, parentComponent: Component, callback: Consumer<SubmittedReportInfo>, project: Project?): Boolean {
|
||||
private fun submit(errorBean: ErrorBean, callback: Consumer<SubmittedReportInfo>, parentComponent: Component, project: Project?): Boolean {
|
||||
var credentials = ErrorReportConfigurable.getCredentials()
|
||||
if (credentials.hasOnlyUserName()) {
|
||||
// ask password only if user name was specified
|
||||
if (!showJetBrainsAccountDialog(parentComponent).showAndGet()) {
|
||||
return false
|
||||
}
|
||||
credentials = ErrorReportConfigurable.getCredentials()
|
||||
credentials = askJBAccountCredentials(parentComponent, project)
|
||||
if (credentials == null) return false
|
||||
}
|
||||
submit(credentials, errorBean, callback, parentComponent, project)
|
||||
return true
|
||||
}
|
||||
|
||||
private fun submit(credentials: Credentials?, errorBean: ErrorBean, callback: Consumer<SubmittedReportInfo>, parentComponent: Component, project: Project?) {
|
||||
ITNProxy.sendError(project, credentials?.userName, credentials?.getPasswordAsString(), errorBean,
|
||||
{ threadId -> onSuccess(threadId, errorBean.event.data, callback, project) },
|
||||
{ e -> onError(e, errorBean, parentComponent, callback, project) })
|
||||
return true
|
||||
{ e -> onError(e, errorBean, callback, parentComponent, project) })
|
||||
}
|
||||
|
||||
private fun onSuccess(threadId: Int, eventData: Any?, callback: Consumer<SubmittedReportInfo>, project: Project?) {
|
||||
@@ -104,7 +104,7 @@ private fun onSuccess(threadId: Int, eventData: Any?, callback: Consumer<Submitt
|
||||
}
|
||||
}
|
||||
|
||||
private fun onError(e: Exception, errorBean: ErrorBean, parentComponent: Component, callback: Consumer<SubmittedReportInfo>, project: Project?) {
|
||||
private fun onError(e: Exception, errorBean: ErrorBean, callback: Consumer<SubmittedReportInfo>, parentComponent: Component, project: Project?) {
|
||||
Logger.getInstance(ITNReporter::class.java).info("reporting failed: $e")
|
||||
ApplicationManager.getApplication().invokeLater {
|
||||
if (e is UpdateAvailableException) {
|
||||
@@ -112,24 +112,24 @@ private fun onError(e: Exception, errorBean: ErrorBean, parentComponent: Compone
|
||||
val title = CommonBundle.getWarningTitle()
|
||||
val icon = Messages.getWarningIcon()
|
||||
if (parentComponent.isShowing) Messages.showMessageDialog(parentComponent, message, title, icon)
|
||||
else Messages.showMessageDialog(project, message, title, icon)
|
||||
else Messages.showMessageDialog(project, message, title, icon)
|
||||
callback.consume(SubmittedReportInfo(SubmittedReportInfo.SubmissionStatus.FAILED))
|
||||
return@invokeLater
|
||||
}
|
||||
|
||||
val msg = when (e) {
|
||||
is NoSuchEAPUserException -> DiagnosticBundle.message("error.report.authentication.failed")
|
||||
is InternalEAPException -> DiagnosticBundle.message("error.report.posting.failed", e.message)
|
||||
else -> DiagnosticBundle.message("error.report.sending.failure")
|
||||
}
|
||||
if (!MessageDialogBuilder.yesNo(ReportMessages.ERROR_REPORT, msg).project(project).isYes) {
|
||||
callback.consume(SubmittedReportInfo(SubmittedReportInfo.SubmissionStatus.FAILED))
|
||||
else if (e is NoSuchEAPUserException) {
|
||||
val credentials = askJBAccountCredentials(parentComponent, project, true)
|
||||
if (credentials != null) {
|
||||
submit(credentials, errorBean, callback, parentComponent, project)
|
||||
}
|
||||
else {
|
||||
callback.consume(SubmittedReportInfo(SubmittedReportInfo.SubmissionStatus.FAILED))
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (e is NoSuchEAPUserException) {
|
||||
showJetBrainsAccountDialog(parentComponent, project).show()
|
||||
val message = DiagnosticBundle.message("error.report.posting.failed", e.message)
|
||||
val result = MessageDialogBuilder.yesNo(ReportMessages.ERROR_REPORT, message).project(project).show()
|
||||
if (result != Messages.YES || !submit(errorBean, callback, parentComponent, project)) {
|
||||
callback.consume(SubmittedReportInfo(SubmittedReportInfo.SubmissionStatus.FAILED))
|
||||
}
|
||||
ApplicationManager.getApplication().invokeLater { submit(errorBean, parentComponent, callback, project) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -287,7 +287,7 @@ public class IdeErrorsDialog extends DialogWrapper implements MessagePoolListene
|
||||
myCredentialsLabel = new HyperlinkLabel();
|
||||
myCredentialsLabel.addHyperlinkListener(e -> {
|
||||
if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
|
||||
JetBrainsAccountDialogKt.showJetBrainsAccountDialog(getRootPane()).show();
|
||||
JetBrainsAccountDialogKt.askJBAccountCredentials(getRootPane(), null);
|
||||
updateControls();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -14,10 +14,61 @@ import com.intellij.ui.components.dialog
|
||||
import com.intellij.ui.layout.*
|
||||
import com.intellij.util.io.encodeUrlQueryParameter
|
||||
import com.intellij.util.text.nullize
|
||||
import org.jetbrains.annotations.ApiStatus
|
||||
import java.awt.Component
|
||||
import javax.swing.JPasswordField
|
||||
import javax.swing.JTextField
|
||||
|
||||
@JvmOverloads
|
||||
fun askJBAccountCredentials(parent: Component, project: Project?, authFailed: Boolean = false): Credentials? {
|
||||
val credentials = ErrorReportConfigurable.getCredentials()
|
||||
val remember = if (credentials?.userName == null) PasswordSafe.instance.isRememberPasswordByDefault // EA credentials were never stored
|
||||
else !credentials.password.isNullOrEmpty() // a password was stored already
|
||||
|
||||
val prompt = if (authFailed) DiagnosticBundle.message("error.report.auth.failed")
|
||||
else DiagnosticBundle.message("error.report.auth.prompt")
|
||||
val userField = JTextField(credentials?.userName)
|
||||
val passwordField = JPasswordField(credentials?.password?.toString())
|
||||
val rememberCheckBox = CheckBox(CommonBundle.message("checkbox.remember.password"), remember)
|
||||
|
||||
val panel = panel {
|
||||
noteRow(prompt)
|
||||
row(DiagnosticBundle.message("error.report.auth.user")) { userField(growPolicy = GrowPolicy.SHORT_TEXT) }
|
||||
row(DiagnosticBundle.message("error.report.auth.pass")) { passwordField() }
|
||||
row {
|
||||
rememberCheckBox()
|
||||
right {
|
||||
link(DiagnosticBundle.message("error.report.auth.restore")) {
|
||||
val userName = userField.text.trim().encodeUrlQueryParameter()
|
||||
BrowserUtil.browse("https://account.jetbrains.com/forgot-password?username=$userName")
|
||||
}
|
||||
}
|
||||
}
|
||||
noteRow(DiagnosticBundle.message("error.report.auth.enlist", "https://account.jetbrains.com/login?signup"))
|
||||
}
|
||||
|
||||
val dialog = dialog(
|
||||
title = DiagnosticBundle.message("error.report.title"),
|
||||
panel = panel,
|
||||
focusedComponent = if (credentials?.userName == null) userField else passwordField,
|
||||
project = project,
|
||||
parent = if (parent.isShowing) parent else null)
|
||||
|
||||
if (!dialog.showAndGet()) {
|
||||
return null
|
||||
}
|
||||
|
||||
val userName = userField.text.nullize(true)
|
||||
val password = passwordField.password
|
||||
val passwordToRemember = if (rememberCheckBox.isSelected) password else null
|
||||
RememberCheckBoxState.update(rememberCheckBox)
|
||||
PasswordSafe.instance.set(CredentialAttributes(ErrorReportConfigurable.SERVICE_NAME, userName), Credentials(userName, passwordToRemember))
|
||||
return Credentials(userName, password)
|
||||
}
|
||||
|
||||
//<editor-fold desc="Deprecated stuff.">
|
||||
@Deprecated("use #askJBAccountCredentials()")
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2020")
|
||||
@JvmOverloads
|
||||
fun showJetBrainsAccountDialog(parent: Component, project: Project? = null): DialogWrapper {
|
||||
val credentials = ErrorReportConfigurable.getCredentials()
|
||||
@@ -64,4 +115,5 @@ fun showJetBrainsAccountDialog(parent: Component, project: Project? = null): Dia
|
||||
passwordSafe.set(CredentialAttributes(ErrorReportConfigurable.SERVICE_NAME, userName), Credentials(userName, password))
|
||||
return@dialog null
|
||||
}
|
||||
}
|
||||
}
|
||||
//</editor-fold>
|
||||
@@ -57,14 +57,23 @@ error.dialog.notice.named=<html>I agree to my names, email address, username, pa
|
||||
|
||||
title.submitting.error.report=Submitting Error Report
|
||||
error.report.gratitude=Thank you for your feedback!
|
||||
error.report.authentication.failed=JetBrains Account authentication failed. Do you want to try again?
|
||||
error.report.posting.failed=Report posting failed: {0}. Do you want to try again?
|
||||
error.report.posting.failed=Report sending failed: {0}. Do you want to try again?
|
||||
error.report.new.eap.build.message=New build {0} is available.
|
||||
error.report.sending.failure=Sending failed. Do you want to try again?
|
||||
error.itn.returns.wrong.data=ITN returns wrong data
|
||||
error.http.result.code=HTTP Result code: {0}
|
||||
error.report.failure.message=Error report sending failed.
|
||||
|
||||
error.report.auth.prompt=Use JetBrains Account credentials to be notified\n \
|
||||
when reported exceptions are fixed.\n \
|
||||
Clear user name to submit reports anonymously.
|
||||
error.report.auth.failed=JetBrains Account authentication failed.\n \
|
||||
Please check your user name and password.\n \
|
||||
Clear user name to submit reports anonymously.
|
||||
error.report.auth.user=&Username:
|
||||
error.report.auth.pass=&Password:
|
||||
error.report.auth.restore=Forgot password?
|
||||
error.report.auth.enlist=Do not have an account yet? <a href="{0}">Sign Up</a>.
|
||||
|
||||
error.dialog.disable.plugin.title=Disable Plugin
|
||||
error.dialog.disable.prompt=Are you sure you want to disable plugin <b>{0}</b>?
|
||||
error.dialog.disable.prompt.lone=Functionality provided by the plugin will no longer be available.
|
||||
|
||||
+6
-1
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.structuralsearch;
|
||||
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
@@ -132,4 +132,9 @@ public class OptimizedSearchScanTest extends StructuralSearchTestCase {
|
||||
final String plan = findWordsToBeUsedWhenSearchingFor("assert '_exp != null && true: \"'_exp is null\";");
|
||||
assertEquals("[in literals:null][in literals:is][in code:assert][in code:null][in code:true]", plan);
|
||||
}
|
||||
|
||||
public void testClassObjectAccessExpression() {
|
||||
final String plan = findWordsToBeUsedWhenSearchingFor("ArrayUtil.toObjectArray($var$, $class$.class)");
|
||||
assertEquals("[in code:toObjectArray][in code:ArrayUtil][in code:class]", plan);
|
||||
}
|
||||
}
|
||||
|
||||
+9
-6
@@ -1,13 +1,16 @@
|
||||
<html>
|
||||
<body>
|
||||
Reports integer multiplication or left shift
|
||||
which are implicitly cast to long.
|
||||
Such multiplication is often an error, as overflow truncation may occur unexpectedly.
|
||||
Reports integer multiplications or left shifts which are implicitly cast to long.
|
||||
For example:
|
||||
<pre><code>
|
||||
<b>void</b> x(int i) {
|
||||
<b>long</b> val = 65536 * i;
|
||||
}
|
||||
</code></pre>
|
||||
Such multiplication is often a mistake, as overflow truncation may occur unexpectedly.
|
||||
Converting the <b>int</b> literal to a <b>long</b> literal (<code>65536L</code>) fixes the problem.
|
||||
<!-- tooltip end -->
|
||||
<p>
|
||||
Use the checkbox below to ignore compile time constant expressions which evaluate to
|
||||
a non-overflowing value.
|
||||
<p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,7 +1,7 @@
|
||||
<html>
|
||||
<body>
|
||||
Reports <b>if</b> statements which can be simplified to single assignment,
|
||||
<b>return</b> or <b>assert</b> statements.
|
||||
Reports <b>if</b> statements which can be simplified to a single assignment,
|
||||
<b>return</b> or <b>assert</b> statement.
|
||||
<p>
|
||||
For example:
|
||||
<code><pre>
|
||||
|
||||
+71
-49
@@ -172,8 +172,11 @@ public class GroovyGeneratedParser implements PsiParser, LightPsiParser {
|
||||
else if (t == LABELED_STATEMENT) {
|
||||
r = labeled_statement(b, 0);
|
||||
}
|
||||
else if (t == LAMBDA_BLOCK) {
|
||||
r = lambda_block(b, 0);
|
||||
else if (t == LAMBDA_BLOCK_FORM_BODY) {
|
||||
r = lambda_block_form_body(b, 0);
|
||||
}
|
||||
else if (t == LAMBDA_EXPRESSION_FORM_BODY) {
|
||||
r = lambda_expression_form_body(b, 0);
|
||||
}
|
||||
else if (t == LEFT_SHIFT_SIGN) {
|
||||
r = left_shift_sign(b, 0);
|
||||
@@ -4301,8 +4304,8 @@ public class GroovyGeneratedParser implements PsiParser, LightPsiParser {
|
||||
|
||||
/* ********************************************************** */
|
||||
// '{' mb_nl block_levels '}'
|
||||
public static boolean lambda_block(PsiBuilder b, int l) {
|
||||
if (!recursion_guard_(b, l, "lambda_block")) return false;
|
||||
public static boolean lambda_block_form_body(PsiBuilder b, int l) {
|
||||
if (!recursion_guard_(b, l, "lambda_block_form_body")) return false;
|
||||
if (!nextTokenIsFast(b, T_LBRACE)) return false;
|
||||
boolean r;
|
||||
Marker m = enter_section_(b);
|
||||
@@ -4310,18 +4313,18 @@ public class GroovyGeneratedParser implements PsiParser, LightPsiParser {
|
||||
r = r && mb_nl(b, l + 1);
|
||||
r = r && block_levels(b, l + 1);
|
||||
r = r && consumeToken(b, T_RBRACE);
|
||||
exit_section_(b, m, LAMBDA_BLOCK, r);
|
||||
exit_section_(b, m, LAMBDA_BLOCK_FORM_BODY, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* ********************************************************** */
|
||||
// (!<<isParameterizedClosure>> lazy_lambda_block) | expression_or_application
|
||||
// (!<<isParameterizedClosure>> lazy_lambda_block) | lambda_expression_form_body
|
||||
static boolean lambda_body(PsiBuilder b, int l) {
|
||||
if (!recursion_guard_(b, l, "lambda_body")) return false;
|
||||
boolean r;
|
||||
Marker m = enter_section_(b);
|
||||
r = lambda_body_0(b, l + 1);
|
||||
if (!r) r = expression_or_application(b, l + 1);
|
||||
if (!r) r = lambda_expression_form_body(b, l + 1);
|
||||
exit_section_(b, m, null, r);
|
||||
return r;
|
||||
}
|
||||
@@ -4362,6 +4365,17 @@ public class GroovyGeneratedParser implements PsiParser, LightPsiParser {
|
||||
return r || p;
|
||||
}
|
||||
|
||||
/* ********************************************************** */
|
||||
// expression_or_application
|
||||
public static boolean lambda_expression_form_body(PsiBuilder b, int l) {
|
||||
if (!recursion_guard_(b, l, "lambda_expression_form_body")) return false;
|
||||
boolean r;
|
||||
Marker m = enter_section_(b, l, _NONE_, LAMBDA_EXPRESSION_FORM_BODY, "<lambda expression form body>");
|
||||
r = expression_or_application(b, l + 1);
|
||||
exit_section_(b, l, m, r, false, null);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* ********************************************************** */
|
||||
// lambda_parameter_list mb_nl '->'
|
||||
static boolean lambda_expression_head(PsiBuilder b, int l) {
|
||||
@@ -4435,12 +4449,12 @@ public class GroovyGeneratedParser implements PsiParser, LightPsiParser {
|
||||
}
|
||||
|
||||
/* ********************************************************** */
|
||||
// <<parseBlockLazy lambda_block 'LAMBDA_BLOCK'>>
|
||||
// <<parseBlockLazy lambda_block_form_body 'LAMBDA_BLOCK_FORM_BODY'>>
|
||||
public static boolean lazy_lambda_block(PsiBuilder b, int l) {
|
||||
if (!recursion_guard_(b, l, "lazy_lambda_block")) return false;
|
||||
boolean r;
|
||||
Marker m = enter_section_(b, l, _COLLAPSE_, LAMBDA_BLOCK, "<lazy lambda block>");
|
||||
r = parseBlockLazy(b, l + 1, GroovyGeneratedParser::lambda_block, LAMBDA_BLOCK);
|
||||
Marker m = enter_section_(b, l, _COLLAPSE_, LAMBDA_BLOCK_FORM_BODY, "<lazy lambda block>");
|
||||
r = parseBlockLazy(b, l + 1, GroovyGeneratedParser::lambda_block_form_body, LAMBDA_BLOCK_FORM_BODY);
|
||||
exit_section_(b, l, m, r, false, null);
|
||||
return r;
|
||||
}
|
||||
@@ -6038,49 +6052,12 @@ public class GroovyGeneratedParser implements PsiParser, LightPsiParser {
|
||||
}
|
||||
|
||||
/* ********************************************************** */
|
||||
// <<isParameterizedClosure>> expression_or_application
|
||||
// | expression_or_application !<<isParsedAsClosure>>
|
||||
// | lazy_lambda_block
|
||||
// single_argument_lambda_expression_form_body | lazy_lambda_block
|
||||
static boolean single_argument_lambda_body(PsiBuilder b, int l) {
|
||||
if (!recursion_guard_(b, l, "single_argument_lambda_body")) return false;
|
||||
boolean r;
|
||||
Marker m = enter_section_(b);
|
||||
r = single_argument_lambda_body_0(b, l + 1);
|
||||
if (!r) r = single_argument_lambda_body_1(b, l + 1);
|
||||
r = single_argument_lambda_expression_form_body(b, l + 1);
|
||||
if (!r) r = lazy_lambda_block(b, l + 1);
|
||||
exit_section_(b, m, null, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
// <<isParameterizedClosure>> expression_or_application
|
||||
private static boolean single_argument_lambda_body_0(PsiBuilder b, int l) {
|
||||
if (!recursion_guard_(b, l, "single_argument_lambda_body_0")) return false;
|
||||
boolean r;
|
||||
Marker m = enter_section_(b);
|
||||
r = isParameterizedClosure(b, l + 1);
|
||||
r = r && expression_or_application(b, l + 1);
|
||||
exit_section_(b, m, null, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
// expression_or_application !<<isParsedAsClosure>>
|
||||
private static boolean single_argument_lambda_body_1(PsiBuilder b, int l) {
|
||||
if (!recursion_guard_(b, l, "single_argument_lambda_body_1")) return false;
|
||||
boolean r;
|
||||
Marker m = enter_section_(b);
|
||||
r = expression_or_application(b, l + 1);
|
||||
r = r && single_argument_lambda_body_1_1(b, l + 1);
|
||||
exit_section_(b, m, null, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
// !<<isParsedAsClosure>>
|
||||
private static boolean single_argument_lambda_body_1_1(PsiBuilder b, int l) {
|
||||
if (!recursion_guard_(b, l, "single_argument_lambda_body_1_1")) return false;
|
||||
boolean r;
|
||||
Marker m = enter_section_(b, l, _NOT_);
|
||||
r = !isParsedAsClosure(b, l + 1);
|
||||
exit_section_(b, l, m, r, false, null);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -6098,6 +6075,51 @@ public class GroovyGeneratedParser implements PsiParser, LightPsiParser {
|
||||
return r || p;
|
||||
}
|
||||
|
||||
/* ********************************************************** */
|
||||
// <<isParameterizedClosure>> expression_or_application
|
||||
// | expression_or_application !<<isParsedAsClosure>>
|
||||
static boolean single_argument_lambda_expression_form_body(PsiBuilder b, int l) {
|
||||
if (!recursion_guard_(b, l, "single_argument_lambda_expression_form_body")) return false;
|
||||
boolean r;
|
||||
Marker m = enter_section_(b);
|
||||
r = single_argument_lambda_expression_form_body_0(b, l + 1);
|
||||
if (!r) r = single_argument_lambda_expression_form_body_1(b, l + 1);
|
||||
exit_section_(b, m, null, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
// <<isParameterizedClosure>> expression_or_application
|
||||
private static boolean single_argument_lambda_expression_form_body_0(PsiBuilder b, int l) {
|
||||
if (!recursion_guard_(b, l, "single_argument_lambda_expression_form_body_0")) return false;
|
||||
boolean r;
|
||||
Marker m = enter_section_(b);
|
||||
r = isParameterizedClosure(b, l + 1);
|
||||
r = r && expression_or_application(b, l + 1);
|
||||
exit_section_(b, m, null, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
// expression_or_application !<<isParsedAsClosure>>
|
||||
private static boolean single_argument_lambda_expression_form_body_1(PsiBuilder b, int l) {
|
||||
if (!recursion_guard_(b, l, "single_argument_lambda_expression_form_body_1")) return false;
|
||||
boolean r;
|
||||
Marker m = enter_section_(b);
|
||||
r = expression_or_application(b, l + 1);
|
||||
r = r && single_argument_lambda_expression_form_body_1_1(b, l + 1);
|
||||
exit_section_(b, m, null, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
// !<<isParsedAsClosure>>
|
||||
private static boolean single_argument_lambda_expression_form_body_1_1(PsiBuilder b, int l) {
|
||||
if (!recursion_guard_(b, l, "single_argument_lambda_expression_form_body_1_1")) return false;
|
||||
boolean r;
|
||||
Marker m = enter_section_(b, l, _NOT_);
|
||||
r = !isParsedAsClosure(b, l + 1);
|
||||
exit_section_(b, l, m, r, false, null);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* ********************************************************** */
|
||||
// single_argument_lambda_parameter_list mb_nl '->'
|
||||
static boolean single_argument_lambda_expression_head(PsiBuilder b, int l) {
|
||||
|
||||
+3
-2
@@ -24,7 +24,7 @@ import org.jetbrains.plugins.groovy.lang.psi.stubs.elements.GrFieldElementType;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.stubs.elements.GrImplementsClauseElementType;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.stubs.elements.GrImportStatementElementType;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.stubs.elements.GrInterfaceDefinitionElementType;
|
||||
import org.jetbrains.plugins.groovy.lang.parser.GrLambdaBlockElementType;
|
||||
import org.jetbrains.plugins.groovy.lang.parser.GrLambdaBlockFormBodyElementType;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.stubs.elements.GrMethodElementType;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.stubs.elements.GrModifierListElementType;
|
||||
import org.jetbrains.plugins.groovy.lang.parser.GrBlockElementType;
|
||||
@@ -107,8 +107,9 @@ public interface GroovyElementTypes {
|
||||
GrInterfaceDefinitionElementType INTERFACE_TYPE_DEFINITION = new GrInterfaceDefinitionElementType("INTERFACE_TYPE_DEFINITION");
|
||||
GroovyElementType IN_EXPRESSION = new GroovyElementType("IN_EXPRESSION");
|
||||
GroovyElementType LABELED_STATEMENT = new GroovyElementType("LABELED_STATEMENT");
|
||||
GrLambdaBlockElementType LAMBDA_BLOCK = new GrLambdaBlockElementType("LAMBDA_BLOCK");
|
||||
GrLambdaBlockFormBodyElementType LAMBDA_BLOCK_FORM_BODY = new GrLambdaBlockFormBodyElementType("LAMBDA_BLOCK_FORM_BODY");
|
||||
GroovyElementType LAMBDA_EXPRESSION = new GroovyElementType("LAMBDA_EXPRESSION");
|
||||
GroovyElementType LAMBDA_EXPRESSION_FORM_BODY = new GroovyElementType("LAMBDA_EXPRESSION_FORM_BODY");
|
||||
GroovyElementType LAND_EXPRESSION = new GroovyElementType("LAND_EXPRESSION");
|
||||
GroovyElementType LEFT_SHIFT_SIGN = new GroovyElementType("LEFT_SHIFT_SIGN");
|
||||
GroovyElementType LIST_OR_MAP = new GroovyElementType("LIST_OR_MAP");
|
||||
|
||||
+4
-4
@@ -3,17 +3,17 @@ package org.jetbrains.plugins.groovy.lang.parser;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.blocks.GrBlockImpl;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GrLambdaBlockImpl;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GrLambdaBodyBlockImpl;
|
||||
|
||||
public class GrLambdaBlockElementType extends GrCodeBlockElementType {
|
||||
public class GrLambdaBlockFormBodyElementType extends GrCodeBlockElementType {
|
||||
|
||||
public GrLambdaBlockElementType(String debugName) {
|
||||
public GrLambdaBlockFormBodyElementType(String debugName) {
|
||||
super(debugName);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public GrBlockImpl createNode(CharSequence text) {
|
||||
return new GrLambdaBlockImpl(this, text);
|
||||
return new GrLambdaBodyBlockImpl(this, text);
|
||||
}
|
||||
}
|
||||
+1
@@ -205,6 +205,7 @@ public class GroovyPsiCreator {
|
||||
if (elem == ARRAY_DECLARATION) return new GrArrayDeclarationImpl(node);
|
||||
if (elem == ARRAY_INITIALIZER) return new GrArrayInitializerImpl(node);
|
||||
if (elem == LAMBDA_EXPRESSION) return new GrLambdaExpressionImpl(node);
|
||||
if (elem == LAMBDA_EXPRESSION_FORM_BODY) return new GrLambdaBodyExpressionImpl(node);
|
||||
|
||||
//Paths
|
||||
if (elem == REFERENCE_EXPRESSION) return new GrReferenceExpressionImpl(node);
|
||||
|
||||
@@ -943,11 +943,14 @@ constructor_call_expression ::= &('this' | 'super') unqualified_reference_expres
|
||||
method_call_expression ::= expression call_tail
|
||||
private call_tail ::= call_argument_list (mb_nl lazy_closure)* | empty_argument_list <<closureArgumentSeparator lazy_closure+>>
|
||||
|
||||
//region Lambda expression
|
||||
lambda_expression ::= lambda_expression_base | clear_variants_and_fail
|
||||
private lambda_expression_base ::= lambda_expression_head mb_nl lambda_body { pin = 1 }
|
||||
private lambda_expression_head ::= lambda_parameter_list mb_nl '->' { consumeTokenMethod = 'consumeTokenFast' }
|
||||
lambda_parameter_list ::= empty_parens | '(' <<comma_list (mb_nl parse_parameter)>> ')' { elementType = parameter_list }
|
||||
private lambda_body ::= (!<<isParameterizedClosure>> lazy_lambda_block) | expression_or_application
|
||||
private lambda_body ::= (!<<isParameterizedClosure>> lazy_lambda_block) | lambda_expression_form_body
|
||||
|
||||
lambda_expression_form_body ::= expression_or_application
|
||||
|
||||
single_argument_lambda_expression::= single_argument_lambda_expression_base | clear_variants_and_fail { elementType = lambda_expression }
|
||||
private single_argument_lambda_expression_base ::= single_argument_lambda_expression_head mb_nl single_argument_lambda_body { pin = 1 }
|
||||
@@ -957,18 +960,22 @@ single_argument_lambda_parameter_list ::= !<<isApplicationArguments>> single_arg
|
||||
single_argument_lambda_parameter ::= modifier_list IDENTIFIER {
|
||||
elementType = parameter
|
||||
}
|
||||
private single_argument_lambda_body ::= <<isParameterizedClosure>> expression_or_application
|
||||
| expression_or_application !<<isParsedAsClosure>>
|
||||
| lazy_lambda_block
|
||||
|
||||
lazy_lambda_block ::= <<parseBlockLazy lambda_block 'LAMBDA_BLOCK'>> {
|
||||
elementType = lambda_block
|
||||
private single_argument_lambda_body ::= single_argument_lambda_expression_form_body | lazy_lambda_block
|
||||
private single_argument_lambda_expression_form_body ::= <<isParameterizedClosure>> expression_or_application
|
||||
| expression_or_application !<<isParsedAsClosure>>
|
||||
{
|
||||
elementType = lambda_expression_form_body
|
||||
}
|
||||
|
||||
lambda_block ::= '{' mb_nl block_levels '}' {
|
||||
elementTypeClass = 'org.jetbrains.plugins.groovy.lang.parser.GrLambdaBlockElementType'
|
||||
lazy_lambda_block ::= <<parseBlockLazy lambda_block_form_body 'LAMBDA_BLOCK_FORM_BODY'>> {
|
||||
elementType = lambda_block_form_body
|
||||
}
|
||||
|
||||
lambda_block_form_body ::= '{' mb_nl block_levels '}' {
|
||||
elementTypeClass = 'org.jetbrains.plugins.groovy.lang.parser.GrLambdaBlockFormBodyElementType'
|
||||
consumeTokenMethod = 'consumeTokenFast'
|
||||
}
|
||||
// endregion
|
||||
|
||||
lazy_closure ::= <<parseBlockLazy closure 'CLOSURE'>>
|
||||
{
|
||||
|
||||
+8
-4
@@ -58,7 +58,11 @@ public abstract class GroovyElementVisitor {
|
||||
}
|
||||
|
||||
public void visitClosure(@NotNull GrClosableBlock closure) {
|
||||
visitStatement(closure);
|
||||
visitFunctionalExpression(closure);
|
||||
}
|
||||
|
||||
public void visitFunctionalExpression(@NotNull GrFunctionalExpression expression) {
|
||||
visitExpression(expression);
|
||||
}
|
||||
|
||||
public void visitOpenBlock(@NotNull GrOpenBlock block) {
|
||||
@@ -66,11 +70,11 @@ public abstract class GroovyElementVisitor {
|
||||
}
|
||||
|
||||
public void visitLambdaExpression(@NotNull GrLambdaExpression expression) {
|
||||
visitExpression(expression);
|
||||
visitFunctionalExpression(expression);
|
||||
}
|
||||
|
||||
public void visitLambdaBlock(@NotNull GrCodeBlock block) {
|
||||
visitElement(block);
|
||||
public void visitLambdaBody(@NotNull GrLambdaBody body) {
|
||||
visitElement(body);
|
||||
}
|
||||
|
||||
public void visitEnumConstants(@NotNull GrEnumConstantList enumConstantsSection) {
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package org.jetbrains.plugins.groovy.lang.psi.api;
|
||||
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GrControlFlowOwner;
|
||||
|
||||
/**
|
||||
* Represents a Groovy lambda expression body.
|
||||
*/
|
||||
public interface GrLambdaBody extends GrControlFlowOwner {
|
||||
}
|
||||
+2
-5
@@ -1,20 +1,17 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package org.jetbrains.plugins.groovy.lang.psi.api;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
|
||||
|
||||
/**
|
||||
* Represents a Groovy lambda expression.
|
||||
*/
|
||||
public interface GrLambdaExpression extends GrFunctionalExpression {
|
||||
/**
|
||||
* Returns PSI element representing lambda expression body: {@link org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock}, {@link GrExpression},
|
||||
* or null if the expression is incomplete.
|
||||
* Returns PSI element representing lambda expression body or null if the expression is incomplete.
|
||||
*
|
||||
* @return lambda expression body.
|
||||
*/
|
||||
@Nullable
|
||||
PsiElement getBody();
|
||||
GrLambdaBody getBody();
|
||||
}
|
||||
|
||||
+4
-3
@@ -4,17 +4,18 @@ package org.jetbrains.plugins.groovy.lang.psi.impl;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.GrLambdaBody;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.blocks.GrBlockImpl;
|
||||
|
||||
public class GrLambdaBlockImpl extends GrBlockImpl {
|
||||
public class GrLambdaBodyBlockImpl extends GrBlockImpl implements GrLambdaBody {
|
||||
|
||||
public GrLambdaBlockImpl(@NotNull IElementType type, CharSequence buffer) {
|
||||
public GrLambdaBodyBlockImpl(@NotNull IElementType type, CharSequence buffer) {
|
||||
super(type, buffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(@NotNull GroovyElementVisitor visitor) {
|
||||
visitor.visitLambdaBlock(this);
|
||||
visitor.visitLambdaBody(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package org.jetbrains.plugins.groovy.lang.psi.impl
|
||||
|
||||
import com.intellij.lang.ASTNode
|
||||
import com.intellij.util.IncorrectOperationException
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.GrLambdaBody
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression
|
||||
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction
|
||||
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.impl.ControlFlowBuilder
|
||||
|
||||
class GrLambdaBodyExpressionImpl(node: ASTNode) : GroovyPsiElementImpl(node), GrLambdaBody {
|
||||
|
||||
fun getExpression() : GrExpression = findNotNullChildByClass(GrExpression::class.java)
|
||||
|
||||
override fun accept(visitor: GroovyElementVisitor) = visitor.visitLambdaBody(this)
|
||||
|
||||
override fun toString(): String = "Lambda body"
|
||||
|
||||
override fun getControlFlow(): Array<Instruction> = ControlFlowBuilder(project).buildControlFlow(this)
|
||||
|
||||
override fun isTopControlFlowOwner(): Boolean = true
|
||||
|
||||
override fun addStatementBefore(statement: GrStatement, anchor: GrStatement?): GrStatement {
|
||||
throw IncorrectOperationException("Can't add statement in a single expression form of body")
|
||||
}
|
||||
|
||||
override fun getStatements(): Array<GrStatement> = arrayOf(getExpression())
|
||||
}
|
||||
+3
-4
@@ -10,8 +10,7 @@ import com.intellij.psi.util.CachedValueProvider.Result.create
|
||||
import com.intellij.psi.util.CachedValuesManager.getCachedValue
|
||||
import com.intellij.psi.util.PsiModificationTracker
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrCodeBlock
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.GrLambdaBody
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.GrLambdaExpression
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameterList
|
||||
@@ -31,9 +30,9 @@ class GrLambdaExpressionImpl(node: ASTNode) : GrExpressionImpl(node), GrLambdaEx
|
||||
|
||||
override fun isVarArgs(): Boolean = false
|
||||
|
||||
override fun getBody(): PsiElement? {
|
||||
override fun getBody(): GrLambdaBody? {
|
||||
val body = lastChild
|
||||
return if (body is GrExpression || body is GrCodeBlock) body else null
|
||||
return if (body is GrLambdaBody) body else null
|
||||
}
|
||||
|
||||
override fun processDeclarations(processor: PsiScopeProcessor, state: ResolveState, lastParent: PsiElement?, place: PsiElement): Boolean {
|
||||
|
||||
@@ -21,5 +21,6 @@ Groovy script
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(->)('->')
|
||||
PsiWhiteSpace(' ')
|
||||
Reference expression
|
||||
PsiElement(identifier)('a')
|
||||
Lambda body
|
||||
Reference expression
|
||||
PsiElement(identifier)('a')
|
||||
@@ -23,6 +23,7 @@ Groovy script
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(->)('->')
|
||||
PsiWhiteSpace(' ')
|
||||
Reference expression
|
||||
PsiElement(identifier)('a')
|
||||
Lambda body
|
||||
Reference expression
|
||||
PsiElement(identifier)('a')
|
||||
PsiElement())(')')
|
||||
@@ -17,8 +17,9 @@ Groovy script
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(->)('->')
|
||||
PsiWhiteSpace(' ')
|
||||
Reference expression
|
||||
PsiElement(identifier)('a')
|
||||
Lambda body
|
||||
Reference expression
|
||||
PsiElement(identifier)('a')
|
||||
PsiElement(,)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
Lambda expression
|
||||
@@ -32,5 +33,6 @@ Groovy script
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(->)('->')
|
||||
PsiWhiteSpace(' ')
|
||||
Reference expression
|
||||
PsiElement(identifier)('c')
|
||||
Lambda body
|
||||
Reference expression
|
||||
PsiElement(identifier)('c')
|
||||
@@ -22,8 +22,9 @@ Groovy script
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(->)('->')
|
||||
PsiWhiteSpace(' ')
|
||||
Reference expression
|
||||
PsiElement(identifier)('a')
|
||||
Lambda body
|
||||
Reference expression
|
||||
PsiElement(identifier)('a')
|
||||
PsiElement())(')')
|
||||
PsiElement(,)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
@@ -38,5 +39,6 @@ Groovy script
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(->)('->')
|
||||
PsiWhiteSpace(' ')
|
||||
Reference expression
|
||||
PsiElement(identifier)('c')
|
||||
Lambda body
|
||||
Reference expression
|
||||
PsiElement(identifier)('c')
|
||||
@@ -17,5 +17,6 @@ Groovy script
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(->)('->')
|
||||
PsiWhiteSpace(' ')
|
||||
Reference expression
|
||||
PsiElement(identifier)('a')
|
||||
Lambda body
|
||||
Reference expression
|
||||
PsiElement(identifier)('a')
|
||||
@@ -17,10 +17,11 @@ Groovy script
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(->)('->')
|
||||
PsiWhiteSpace(' ')
|
||||
Call expression
|
||||
Reference expression
|
||||
PsiElement(identifier)('a')
|
||||
PsiWhiteSpace(' ')
|
||||
Command arguments
|
||||
Lambda body
|
||||
Call expression
|
||||
Reference expression
|
||||
PsiElement(identifier)('b')
|
||||
PsiElement(identifier)('a')
|
||||
PsiWhiteSpace(' ')
|
||||
Command arguments
|
||||
Reference expression
|
||||
PsiElement(identifier)('b')
|
||||
+7
-6
@@ -12,10 +12,11 @@ Groovy script
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(->)('->')
|
||||
PsiWhiteSpace(' ')
|
||||
Call expression
|
||||
Reference expression
|
||||
PsiElement(identifier)('a')
|
||||
PsiWhiteSpace(' ')
|
||||
Command arguments
|
||||
Lambda body
|
||||
Call expression
|
||||
Reference expression
|
||||
PsiElement(identifier)('b')
|
||||
PsiElement(identifier)('a')
|
||||
PsiWhiteSpace(' ')
|
||||
Command arguments
|
||||
Reference expression
|
||||
PsiElement(identifier)('b')
|
||||
+3
-2
@@ -28,7 +28,8 @@ Groovy script
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(->)('->')
|
||||
PsiWhiteSpace(' ')
|
||||
Reference expression
|
||||
PsiElement(identifier)('a')
|
||||
Lambda body
|
||||
Reference expression
|
||||
PsiElement(identifier)('a')
|
||||
PsiElement(new line)('\n')
|
||||
PsiElement(})('}')
|
||||
+3
-2
@@ -29,6 +29,7 @@ Groovy script
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(->)('->')
|
||||
PsiWhiteSpace(' ')
|
||||
Reference expression
|
||||
PsiElement(identifier)('a')
|
||||
Lambda body
|
||||
Reference expression
|
||||
PsiElement(identifier)('a')
|
||||
PsiElement())(')')
|
||||
+3
-2
@@ -13,6 +13,7 @@ Groovy script
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(->)('->')
|
||||
PsiWhiteSpace(' ')
|
||||
Reference expression
|
||||
PsiElement(identifier)('a')
|
||||
Lambda body
|
||||
Reference expression
|
||||
PsiElement(identifier)('a')
|
||||
PsiElement())(')')
|
||||
@@ -17,6 +17,7 @@ Groovy script
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(->)('->')
|
||||
PsiWhiteSpace(' ')
|
||||
Reference expression
|
||||
PsiElement(identifier)('a')
|
||||
Lambda body
|
||||
Reference expression
|
||||
PsiElement(identifier)('a')
|
||||
PsiElement())(')')
|
||||
@@ -32,6 +32,7 @@ Groovy script
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(->)('->')
|
||||
PsiWhiteSpace(' ')
|
||||
Reference expression
|
||||
PsiElement(identifier)('a')
|
||||
Lambda body
|
||||
Reference expression
|
||||
PsiElement(identifier)('a')
|
||||
PsiElement())(')')
|
||||
+3
-2
@@ -30,5 +30,6 @@ Groovy script
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(->)('->')
|
||||
PsiWhiteSpace(' ')
|
||||
Reference expression
|
||||
PsiElement(identifier)('b')
|
||||
Lambda body
|
||||
Reference expression
|
||||
PsiElement(identifier)('b')
|
||||
+15
-13
@@ -12,16 +12,18 @@ Groovy script
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(->)('->')
|
||||
PsiWhiteSpace(' ')
|
||||
Lambda expression
|
||||
Parameter list
|
||||
PsiElement(()('(')
|
||||
Parameter
|
||||
Modifiers
|
||||
<empty list>
|
||||
PsiElement(identifier)('b')
|
||||
PsiElement())(')')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(->)('->')
|
||||
PsiWhiteSpace(' ')
|
||||
Reference expression
|
||||
PsiElement(identifier)('b')
|
||||
Lambda body
|
||||
Lambda expression
|
||||
Parameter list
|
||||
PsiElement(()('(')
|
||||
Parameter
|
||||
Modifiers
|
||||
<empty list>
|
||||
PsiElement(identifier)('b')
|
||||
PsiElement())(')')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(->)('->')
|
||||
PsiWhiteSpace(' ')
|
||||
Lambda body
|
||||
Reference expression
|
||||
PsiElement(identifier)('b')
|
||||
+3
-2
@@ -26,7 +26,8 @@ Groovy script
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(->)('->')
|
||||
PsiWhiteSpace(' ')
|
||||
Reference expression
|
||||
PsiElement(identifier)('b')
|
||||
Lambda body
|
||||
Reference expression
|
||||
PsiElement(identifier)('b')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(})('}')
|
||||
+15
-14
@@ -16,18 +16,19 @@ Groovy script
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(->)('->')
|
||||
PsiWhiteSpace(' ')
|
||||
Closable block
|
||||
PsiElement({)('{')
|
||||
PsiWhiteSpace(' ')
|
||||
Parameter list
|
||||
Parameter
|
||||
Modifiers
|
||||
<empty list>
|
||||
Lambda body
|
||||
Closable block
|
||||
PsiElement({)('{')
|
||||
PsiWhiteSpace(' ')
|
||||
Parameter list
|
||||
Parameter
|
||||
Modifiers
|
||||
<empty list>
|
||||
PsiElement(identifier)('b')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(->)('->')
|
||||
PsiWhiteSpace(' ')
|
||||
Reference expression
|
||||
PsiElement(identifier)('b')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(->)('->')
|
||||
PsiWhiteSpace(' ')
|
||||
Reference expression
|
||||
PsiElement(identifier)('b')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(})('}')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(})('}')
|
||||
+12
-11
@@ -13,14 +13,15 @@ Groovy script
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(->)('->')
|
||||
PsiWhiteSpace(' ')
|
||||
Closable block
|
||||
PsiElement({)('{')
|
||||
PsiWhiteSpace(' ')
|
||||
Parameter list
|
||||
<empty list>
|
||||
PsiElement(->)('->')
|
||||
PsiWhiteSpace(' ')
|
||||
Reference expression
|
||||
PsiElement(identifier)('a')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(})('}')
|
||||
Lambda body
|
||||
Closable block
|
||||
PsiElement({)('{')
|
||||
PsiWhiteSpace(' ')
|
||||
Parameter list
|
||||
<empty list>
|
||||
PsiElement(->)('->')
|
||||
PsiWhiteSpace(' ')
|
||||
Reference expression
|
||||
PsiElement(identifier)('a')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(})('}')
|
||||
@@ -31,7 +31,8 @@ Groovy script
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(->)('->')
|
||||
PsiWhiteSpace(' ')
|
||||
Reference expression
|
||||
PsiElement(identifier)('a')
|
||||
Lambda body
|
||||
Reference expression
|
||||
PsiElement(identifier)('a')
|
||||
PsiElement(new line)('\n')
|
||||
PsiElement(})('}')
|
||||
+3
-2
@@ -13,5 +13,6 @@ Groovy script
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(->)('->')
|
||||
PsiWhiteSpace(' ')
|
||||
Reference expression
|
||||
PsiElement(identifier)('a')
|
||||
Lambda body
|
||||
Reference expression
|
||||
PsiElement(identifier)('a')
|
||||
+3
-2
@@ -8,5 +8,6 @@ Groovy script
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(->)('->')
|
||||
PsiWhiteSpace(' ')
|
||||
Reference expression
|
||||
PsiElement(identifier)('a')
|
||||
Lambda body
|
||||
Reference expression
|
||||
PsiElement(identifier)('a')
|
||||
@@ -16,11 +16,12 @@ Groovy script
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(->)('->')
|
||||
PsiWhiteSpace(' ')
|
||||
Method call
|
||||
Reference expression
|
||||
PsiElement(identifier)('print')
|
||||
Arguments
|
||||
PsiElement(()('(')
|
||||
Lambda body
|
||||
Method call
|
||||
Reference expression
|
||||
PsiElement(identifier)('a')
|
||||
PsiElement())(')')
|
||||
PsiElement(identifier)('print')
|
||||
Arguments
|
||||
PsiElement(()('(')
|
||||
Reference expression
|
||||
PsiElement(identifier)('a')
|
||||
PsiElement())(')')
|
||||
@@ -16,5 +16,6 @@ Groovy script
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(->)('->')
|
||||
PsiWhiteSpace(' ')
|
||||
Reference expression
|
||||
PsiElement(identifier)('a')
|
||||
Lambda body
|
||||
Reference expression
|
||||
PsiElement(identifier)('a')
|
||||
Reference in New Issue
Block a user