From 7845df60f74b8a86dec4e8b2e2571a73459ea7be Mon Sep 17 00:00:00 2001 From: Sergey Savenko Date: Wed, 30 Mar 2016 14:15:50 +0900 Subject: [PATCH] Initial "address of a for loop variable" inspection --- resources/META-INF/plugin.xml | 3 ++ .../GoAddressOfLoopVariable.html | 22 ++++++++ .../GoAddressOfLoopVariableInspection.java | 53 +++++++++++++++++++ .../highlighting/addressOfLoopVariable.go | 7 +++ .../goide/inspections/GoHighlightingTest.java | 5 +- 5 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 resources/inspectionDescriptions/GoAddressOfLoopVariable.html create mode 100644 src/com/goide/inspections/GoAddressOfLoopVariableInspection.java create mode 100644 testData/highlighting/addressOfLoopVariable.go diff --git a/resources/META-INF/plugin.xml b/resources/META-INF/plugin.xml index 4d518cecec..23bb05ac21 100644 --- a/resources/META-INF/plugin.xml +++ b/resources/META-INF/plugin.xml @@ -236,6 +236,9 @@ + diff --git a/resources/inspectionDescriptions/GoAddressOfLoopVariable.html b/resources/inspectionDescriptions/GoAddressOfLoopVariable.html new file mode 100644 index 0000000000..d174c4d563 --- /dev/null +++ b/resources/inspectionDescriptions/GoAddressOfLoopVariable.html @@ -0,0 +1,22 @@ + + + + +Checks for obtaining addresses of for loop variables. +Address of a for loop variable remains the same on all iterations of a loop, hence it's probably a bug. + + \ No newline at end of file diff --git a/src/com/goide/inspections/GoAddressOfLoopVariableInspection.java b/src/com/goide/inspections/GoAddressOfLoopVariableInspection.java new file mode 100644 index 0000000000..8cf76fa394 --- /dev/null +++ b/src/com/goide/inspections/GoAddressOfLoopVariableInspection.java @@ -0,0 +1,53 @@ +/* + * Copyright 2013-2016 Sergey Ignatov, Alexander Zolotov, Florin Patan + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.goide.inspections; + +import com.goide.psi.*; +import com.intellij.codeInspection.LocalInspectionToolSession; +import com.intellij.codeInspection.ProblemsHolder; +import com.intellij.psi.PsiElement; +import com.intellij.util.ObjectUtils; +import org.jetbrains.annotations.NotNull; + +public class GoAddressOfLoopVariableInspection extends GoInspectionBase { + @NotNull + @Override + protected GoVisitor buildGoVisitor(@NotNull ProblemsHolder holder, @NotNull LocalInspectionToolSession session) { + return new GoVisitor() { + @Override + public void visitUnaryExpr(@NotNull GoUnaryExpr o) { + if (o.getBitAnd() == null) { + return; + } + + //TODO improve by supporting references to fields of struct variables + GoReferenceExpression refExpr = ObjectUtils.tryCast(o.getExpression(), GoReferenceExpression.class); + if (refExpr == null || refExpr.getQualifier() != null) { + return; + } + + GoVarDefinition varDefinition = ObjectUtils.tryCast(refExpr.getReference().resolve(), GoVarDefinition.class); + PsiElement parent = varDefinition != null ? varDefinition.getParent() : null; + if (!(parent instanceof GoRangeClause)) { + return; + } + + holder.registerProblem(o, "Suspicious: obtaining address of a for loop variable"); + } + }; + } +} diff --git a/testData/highlighting/addressOfLoopVariable.go b/testData/highlighting/addressOfLoopVariable.go new file mode 100644 index 0000000000..2d2c9e2285 --- /dev/null +++ b/testData/highlighting/addressOfLoopVariable.go @@ -0,0 +1,7 @@ +package main + +func main() { + for _, i := range []int{1, 2, 3} { + println(&i) + } +} diff --git a/tests/com/goide/inspections/GoHighlightingTest.java b/tests/com/goide/inspections/GoHighlightingTest.java index 6195c7aa8a..a108a4a1e7 100644 --- a/tests/com/goide/inspections/GoHighlightingTest.java +++ b/tests/com/goide/inspections/GoHighlightingTest.java @@ -66,7 +66,8 @@ public void setUp() throws Exception { GoPlaceholderCountInspection.class, GoEmbeddedInterfacePointerInspection.class, GoStructInitializationInspection.class, - GoMethodOnNonLocalTypeInspection.class + GoMethodOnNonLocalTypeInspection.class, + GoAddressOfLoopVariableInspection.class ); } @@ -350,6 +351,8 @@ public void testUnitializedStructInitialization() { doWeakTest(); } + public void testAddressOfLoopVariable() { doWeakTest(); } + private long doWeakTest() {return myFixture.testHighlighting(true, false, true, getTestName(true) + ".go");} public void testDoNotHighlightCommentOfMainPackage() {