Merge remote-tracking branch 'origin/master'

This commit is contained in:
Dmitry Batkovich
2019-02-06 18:18:17 +03:00
47 changed files with 456 additions and 236 deletions
@@ -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(() -> {
@@ -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>
}
}
}
@@ -0,0 +1,11 @@
// "Insert '(String)x' declaration" "true"
class C {
Object x = new Object();
void x() {
if (x insta<caret>nceof String) {
}
}
}
@@ -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.
@@ -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);
}
}
@@ -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>
@@ -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) {
@@ -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");
@@ -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);
}
}
@@ -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'>>
{
@@ -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) {
@@ -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 {
}
@@ -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,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
@@ -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())
}
@@ -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')
@@ -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')
@@ -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(})('}')
@@ -29,6 +29,7 @@ Groovy script
PsiWhiteSpace(' ')
PsiElement(->)('->')
PsiWhiteSpace(' ')
Reference expression
PsiElement(identifier)('a')
Lambda body
Reference expression
PsiElement(identifier)('a')
PsiElement())(')')
@@ -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())(')')
@@ -30,5 +30,6 @@ Groovy script
PsiWhiteSpace(' ')
PsiElement(->)('->')
PsiWhiteSpace(' ')
Reference expression
PsiElement(identifier)('b')
Lambda body
Reference expression
PsiElement(identifier)('b')
@@ -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')
@@ -26,7 +26,8 @@ Groovy script
PsiWhiteSpace(' ')
PsiElement(->)('->')
PsiWhiteSpace(' ')
Reference expression
PsiElement(identifier)('b')
Lambda body
Reference expression
PsiElement(identifier)('b')
PsiWhiteSpace(' ')
PsiElement(})('}')
@@ -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(})('}')
@@ -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(})('}')
@@ -13,5 +13,6 @@ Groovy script
PsiWhiteSpace(' ')
PsiElement(->)('->')
PsiWhiteSpace(' ')
Reference expression
PsiElement(identifier)('a')
Lambda body
Reference expression
PsiElement(identifier)('a')
@@ -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')