Skip to content

Commit acf10d5

Browse files
committed
Merge pull request #592 from josehsantos/some_fixes
Fix some issues + Add Check error Intention
2 parents ac73ea5 + 40c4a18 commit acf10d5

File tree

19 files changed

+423
-30
lines changed

19 files changed

+423
-30
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
<li>[feature] Fix: Covert or Assert the type of the expression to the expected type in function calls and returns</li>
88
<li>[feature] Intention: For range over expressions</li>
99
<li>[feature] Intention: Generate if block over boolean expressions</li>
10+
<li>[feature] Inspection: Check type of index on index expressions</li>
11+
<li>[feature] Intention: Generate if block over expressions which return errors</li>
1012
</ul>
1113
<h3>0.9.15.3 changes:</h3>
1214
<ul>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package main
2+
3+
func HasErrors()(error,string,error,string){
4+
return nil,"",nil,""
5+
}
6+
7+
func main(){
8+
if err, _, err0, _ := <spot>HasErrors()</spot>; err != nil || err0 != nil {
9+
//TODO: Handle error(s)
10+
}
11+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package main
2+
3+
func HasErrors()(error,string,error,string){
4+
return nil,"",nil,""
5+
}
6+
7+
func main(){
8+
<spot>HasErrors()</spot>
9+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<html>
2+
<body>
3+
Generate an if block to check expressions which return errors
4+
<!-- tooltip end -->
5+
</body>
6+
</html>

src/META-INF/plugin.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
<li>[feature] Intention: For range over expressions</li>
6868
<li>[feature] Intention: Generate if block over boolean expressions</li>
6969
<li>[feature] Inspection: Check type of index on index expressions</li>
70+
<li>[feature] Intention: Generate if block over expressions which return errors</li>
7071
</ul>
7172
<h3>0.9.15.3 changes:</h3>
7273
<ul>
@@ -685,6 +686,12 @@
685686
<className>ro.redeul.google.go.intentions.statements.ConvertStatementToForRangeIntention</className>
686687
</intentionAction>
687688

689+
<intentionAction>
690+
<bundleName>ro.redeul.google.go.intentions.GoIntentionsBundle</bundleName>
691+
<categoryKey>intention.category.go/intention.category.control.flow</categoryKey>
692+
<className>ro.redeul.google.go.intentions.statements.CheckErrorIntention</className>
693+
</intentionAction>
694+
688695
</extensions>
689696

690697
</idea-plugin>

src/ro/redeul/google/go/intentions/GoIntentionsBundle.properties

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,17 +51,20 @@ go.get.intention.family.name=go get
5151
go.get.update.intention.name=Run go get -u
5252
go.get.update.intention.family.name=go get
5353

54-
convert.statement.to.for.while.intention.name=->for
55-
convert.statement.to.for.while.intention.family.name=->for
54+
convert.statement.to.if.intention.name = if
55+
convert.statement.to.if.intention.family.name = control
5656

57-
convert.statement.to.if.intention.name=-->if
58-
convert.statement.to.if.intention.family.name=-->if
57+
check.error.intention.name = check error
58+
check.error.intention.family.name = control
59+
60+
convert.statement.to.for.while.intention.name=loop
61+
convert.statement.to.for.while.intention.family.name=loop
5962

6063
convert.statement.to.for.range.intention.name=for range
61-
convert.statement.to.for.range.intention.family.name=for range
64+
convert.statement.to.for.range.intention.family.name=loop
6265

6366
convert.statement.to.for.i.intention.name=for i
64-
convert.statement.to.for.i.intention.family.name=for i
67+
convert.statement.to.for.i.intention.family.name=loop
6568

6669
error.if.statement.not.found=If statement not found
6770
error.convert.error=Convert error!

src/ro/redeul/google/go/intentions/statements/BaseBoolStatement.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,6 @@
2020

2121
import static ro.redeul.google.go.lang.psi.utils.GoPsiUtils.findParentOfType;
2222

23-
/**
24-
* Created by josesantos on 20/12/13.
25-
*/
2623
public abstract class BaseBoolStatement extends Intention {
2724

2825
protected GoExpressionStatement statement;
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
package ro.redeul.google.go.intentions.statements;
2+
3+
import com.intellij.codeInsight.template.TemplateManager;
4+
import com.intellij.codeInsight.template.impl.TemplateImpl;
5+
import com.intellij.openapi.editor.Document;
6+
import com.intellij.openapi.editor.Editor;
7+
import com.intellij.openapi.editor.RangeMarker;
8+
import com.intellij.openapi.util.TextRange;
9+
import com.intellij.psi.PsiElement;
10+
import com.intellij.psi.PsiWhiteSpace;
11+
import org.jetbrains.annotations.NotNull;
12+
import ro.redeul.google.go.editor.TemplateUtil;
13+
import ro.redeul.google.go.intentions.Intention;
14+
import ro.redeul.google.go.intentions.IntentionExecutionException;
15+
import ro.redeul.google.go.lang.psi.expressions.GoExpr;
16+
import ro.redeul.google.go.lang.psi.statements.GoExpressionStatement;
17+
import ro.redeul.google.go.lang.psi.types.GoPsiType;
18+
import ro.redeul.google.go.lang.psi.types.GoPsiTypeName;
19+
import ro.redeul.google.go.lang.psi.typing.GoType;
20+
import ro.redeul.google.go.lang.psi.typing.GoTypePsiBacked;
21+
import ro.redeul.google.go.lang.psi.utils.GoTypeUtils;
22+
import ro.redeul.google.go.util.GoUtil;
23+
24+
import java.util.ArrayList;
25+
import java.util.List;
26+
27+
import static ro.redeul.google.go.lang.psi.utils.GoPsiUtils.findParentOfType;
28+
29+
public class CheckErrorIntention extends Intention {
30+
31+
protected GoExpressionStatement statement;
32+
protected GoExpr expr;
33+
34+
@Override
35+
protected boolean satisfiedBy(PsiElement element) {
36+
statement = element instanceof GoExpressionStatement ? (GoExpressionStatement) element : findParentOfType(element, GoExpressionStatement.class);
37+
if (statement == null && element instanceof PsiWhiteSpace && element.getPrevSibling() instanceof GoExpressionStatement) {
38+
statement = (GoExpressionStatement) element.getPrevSibling();
39+
}
40+
if (statement != null) {
41+
expr = statement.getExpression();
42+
if (expr != null) {
43+
44+
for (GoType goType : expr.getType()) {
45+
if (goType != null) {
46+
if (goType instanceof GoTypePsiBacked) {
47+
GoPsiType psiType = GoTypeUtils.resolveToFinalType(((GoTypePsiBacked) goType).getPsiType());
48+
if (psiType instanceof GoPsiTypeName) {
49+
if (psiType.getText().equals("error") && ((GoPsiTypeName) psiType).isPrimitive())
50+
return true;
51+
}
52+
}
53+
}
54+
}
55+
}
56+
}
57+
return false;
58+
}
59+
60+
@Override
61+
protected void processIntention(@NotNull PsiElement element, Editor editor) throws IntentionExecutionException {
62+
Document document = editor.getDocument();
63+
TextRange textRange = statement.getTextRange();
64+
RangeMarker range = document.createRangeMarker(textRange.getStartOffset(), textRange.getEndOffset());
65+
document.deleteString(textRange.getStartOffset(), textRange.getEndOffset());
66+
67+
StringBuilder ifString = new StringBuilder();
68+
69+
String k = "err";
70+
ifString.append("if ");
71+
GoType[] types = expr.getType();
72+
List<String> stringList = new ArrayList<String>();
73+
74+
int j = 0;
75+
if (types.length > 1) {
76+
StringBuilder checkString = new StringBuilder();
77+
j = 0;
78+
int c = 0;
79+
int i = 0;
80+
81+
for (GoType goType : types) {
82+
83+
if (j != 0) {
84+
ifString.append(",");
85+
}
86+
87+
String currentVar = String.format("$v%d$", j);
88+
if (goType != null) {
89+
if (goType instanceof GoTypePsiBacked) {
90+
GoPsiType psiType = GoTypeUtils.resolveToFinalType(((GoTypePsiBacked) goType).getPsiType());
91+
if (psiType instanceof GoPsiTypeName && psiType.getText().equals("error") && ((GoPsiTypeName) psiType).isPrimitive()) {
92+
if (k.equals("err") && i != 0)
93+
k = "err0";
94+
while (GoUtil.TestDeclVar(expr, k)) {
95+
k = String.format("err%d", i);
96+
i++;
97+
}
98+
if (c != 0) {
99+
checkString.append(" || ");
100+
}
101+
stringList.add(k);
102+
103+
ifString.append(currentVar);
104+
checkString.append(currentVar)
105+
.append(" != nil");
106+
j++;
107+
i++;
108+
c++;
109+
continue;
110+
}
111+
}
112+
}
113+
ifString.append(currentVar);
114+
stringList.add("_");
115+
j++;
116+
}
117+
118+
ifString
119+
.append(":=")
120+
.append(expr.getText())
121+
.append(";")
122+
.append(checkString)
123+
.append("{");
124+
125+
126+
} else {
127+
ifString
128+
.append(expr.getText())
129+
.append(" != nil {");
130+
131+
}
132+
133+
ifString.append(String.format("\n$v%d$\n}", j));
134+
stringList.add("//TODO: Handle error(s)");
135+
//stringList.add("panic(\"Unhandled error!\")");
136+
TemplateImpl template = TemplateUtil.createTemplate(ifString.toString());
137+
TemplateUtil.setTemplateVariableValues(template, stringList);
138+
String text = editor.getDocument().getText(textRange);
139+
editor.getDocument().deleteString(range.getStartOffset(), range.getEndOffset());
140+
TemplateManager.getInstance(editor.getProject()).startTemplate(editor, "", template);
141+
142+
}
143+
}

src/ro/redeul/google/go/lang/psi/impl/expressions/primary/GoCallOrConvExpressionImpl.java

Lines changed: 88 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,44 +3,120 @@
33
import com.intellij.lang.ASTNode;
44
import com.intellij.psi.PsiElement;
55
import org.jetbrains.annotations.NotNull;
6+
import ro.redeul.google.go.lang.psi.declarations.GoVarDeclaration;
67
import ro.redeul.google.go.lang.psi.expressions.GoExpr;
78
import ro.redeul.google.go.lang.psi.expressions.GoExpressionList;
89
import ro.redeul.google.go.lang.psi.expressions.GoPrimaryExpression;
10+
import ro.redeul.google.go.lang.psi.expressions.literals.GoLiteralFunction;
11+
import ro.redeul.google.go.lang.psi.expressions.literals.GoLiteralIdentifier;
912
import ro.redeul.google.go.lang.psi.expressions.primary.GoCallOrConvExpression;
13+
import ro.redeul.google.go.lang.psi.expressions.primary.GoLiteralExpression;
14+
import ro.redeul.google.go.lang.psi.expressions.primary.GoParenthesisedExpression;
1015
import ro.redeul.google.go.lang.psi.impl.expressions.GoExpressionBase;
1116
import ro.redeul.google.go.lang.psi.toplevel.GoFunctionDeclaration;
1217
import ro.redeul.google.go.lang.psi.toplevel.GoMethodDeclaration;
1318
import ro.redeul.google.go.lang.psi.toplevel.GoTypeSpec;
1419
import ro.redeul.google.go.lang.psi.types.GoPsiType;
20+
import ro.redeul.google.go.lang.psi.types.GoPsiTypeFunction;
1521
import ro.redeul.google.go.lang.psi.typing.GoType;
22+
import ro.redeul.google.go.lang.psi.typing.GoTypePsiBacked;
1623
import ro.redeul.google.go.lang.psi.typing.GoTypes;
24+
import ro.redeul.google.go.lang.psi.utils.GoTypeUtils;
1725
import ro.redeul.google.go.lang.psi.visitors.GoElementVisitor;
26+
import ro.redeul.google.go.util.GoUtil;
1827

1928
import java.util.Arrays;
2029

2130
import static ro.redeul.google.go.lang.psi.utils.GoPsiUtils.resolveSafely;
2231

2332
public class GoCallOrConvExpressionImpl extends GoExpressionBase
24-
implements GoCallOrConvExpression
25-
{
33+
implements GoCallOrConvExpression {
2634
public GoCallOrConvExpressionImpl(@NotNull ASTNode node) {
2735
super(node);
2836
}
2937

3038
@Override
3139
protected GoType[] resolveTypes() {
3240
PsiElement reference = resolveSafely(getBaseExpression(), PsiElement.class);
33-
if (reference == null)
34-
return GoType.EMPTY_ARRAY;
41+
if (reference != null) {
42+
43+
PsiElement parent = reference.getParent();
44+
if (parent instanceof GoMethodDeclaration) {
45+
GoMethodDeclaration declaration = (GoMethodDeclaration) parent;
46+
return GoTypes.fromPsiType(declaration.getReturnType());
47+
}
48+
49+
if (parent instanceof GoFunctionDeclaration) {
50+
GoFunctionDeclaration declaration = (GoFunctionDeclaration) parent;
51+
return GoTypes.fromPsiType(declaration.getReturnType());
52+
}
53+
54+
if (parent instanceof GoVarDeclaration) {
55+
56+
GoLiteralIdentifier[] identifiers = ((GoVarDeclaration) parent).getIdentifiers();
57+
int i;
58+
for (i = 0; i < identifiers.length; i++) {
59+
if (identifiers[i].getText().equals(getBaseExpression().getText())) {
60+
break;
61+
}
62+
}
63+
if (i < identifiers.length)
64+
return resolveVarTypes((GoVarDeclaration) parent, identifiers[i], i);
65+
66+
}
67+
}
68+
69+
GoPrimaryExpression baseExpression = this.getBaseExpression();
70+
if (baseExpression instanceof GoParenthesisedExpression) {
71+
GoType[] types = getBaseExpression().getType();
72+
if (types.length != 0) {
73+
GoType type = types[0];
74+
if (type != null) {
75+
if (type instanceof GoTypePsiBacked) {
76+
GoPsiType psiType = ((GoTypePsiBacked) type).getPsiType();
77+
psiType = GoTypeUtils.resolveToFinalType(psiType);
78+
if (psiType instanceof GoPsiTypeFunction) {
79+
return GoUtil.getFuncCallTypes((GoPsiTypeFunction) psiType);
80+
}
81+
}
82+
}
83+
}
84+
}
85+
86+
if (baseExpression instanceof GoLiteralExpression
87+
&& ((GoLiteralExpression) baseExpression).getLiteral() instanceof GoLiteralFunction) {
88+
return GoUtil.getFuncCallTypes((GoPsiTypeFunction) ((GoLiteralExpression) baseExpression).getLiteral());
89+
}
90+
91+
return GoType.EMPTY_ARRAY;
92+
}
93+
94+
private GoType[] resolveVarTypes(GoVarDeclaration parent, GoLiteralIdentifier identifier, int i) {
95+
96+
GoType identifierType = parent.getIdentifierType(identifier);
97+
if (identifierType != null && identifierType instanceof GoTypePsiBacked) {
98+
GoPsiType goPsiType = GoTypeUtils.resolveToFinalType(((GoTypePsiBacked) identifierType).getPsiType());
99+
if (goPsiType instanceof GoPsiTypeFunction) {
100+
return GoUtil.getFuncCallTypes((GoPsiTypeFunction) goPsiType);
101+
}
102+
}
35103

36-
if (reference.getParent() instanceof GoMethodDeclaration ) {
37-
GoMethodDeclaration declaration = (GoMethodDeclaration)reference.getParent();
38-
return GoTypes.fromPsiType(declaration.getReturnType());
104+
GoExpr[] expressions = parent.getExpressions();
105+
if (expressions.length == 1 && expressions[0] instanceof GoCallOrConvExpression) {
106+
GoType[] types = expressions[0].getType();
107+
if (i < types.length) {
108+
GoType type = types[i];
109+
if (type instanceof GoTypePsiBacked) {
110+
GoPsiType goPsiType = GoTypeUtils.resolveToFinalType(((GoTypePsiBacked) type).getPsiType());
111+
if (goPsiType instanceof GoPsiTypeFunction) {
112+
return GoUtil.getFuncCallTypes((GoPsiTypeFunction) goPsiType);
113+
}
114+
}
115+
}
39116
}
40117

41-
if (reference.getParent() instanceof GoFunctionDeclaration) {
42-
GoFunctionDeclaration declaration = (GoFunctionDeclaration)reference.getParent();
43-
return GoTypes.fromPsiType(declaration.getReturnType());
118+
if (i < expressions.length) {
119+
return expressions[i].getType();
44120
}
45121

46122
return GoType.EMPTY_ARRAY;
@@ -60,11 +136,11 @@ public GoPsiType getTypeArgument() {
60136
public GoExpr[] getArguments() {
61137

62138
GoExpressionList list = findChildByClass(GoExpressionList.class);
63-
if ( list != null ) {
139+
if (list != null) {
64140
return list.getExpressions();
65141
}
66142

67-
GoExpr []expressions = findChildrenByClass(GoExpr.class);
143+
GoExpr[] expressions = findChildrenByClass(GoExpr.class);
68144

69145
if (expressions.length <= 1) {
70146
return GoExpr.EMPTY_ARRAY;

0 commit comments

Comments
 (0)