/* * 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.type; import com.goide.GoCodeInsightFixtureTestCase; import com.goide.SdkAware; import com.goide.psi.GoExpression; import com.goide.psi.impl.GoTypeUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; @SdkAware public class GoExpectedTypesTest extends GoCodeInsightFixtureTestCase { public void testAssignment() { doStatementTest("var a int; a = <selection>asd()</selection>", "int"); } public void testTwoVariablesAssignment() { doStatementTest("var (a int; b string); a, b = <selection>asd()</selection>", "int, string; int"); } public void testTwoVariablesAssignmentWithTeoRightExpressions() { doStatementTest("var (a int; b string); a, b = <selection>asd()</selection>, \"qwe\"", "int"); } public void testTwoVariablesAssignmentWithFewLeftAndRightExpressions() { doStatementTest("var (a, c int; b string); a, b, c = 1, <selection>asd()</selection>, \"qwe\"", "string"); } public void testTwoVariablesAssignmentWithLeftWithoutRightExpressions() { doStatementTest("var (a, c int; b string); a, b, c = 1, <selection>asd()</selection>", "string"); } public void testShortVarDeclaration() { doStatementTest(" c := <selection>asd()</selection>", "interface{}"); } public void testShortVarDeclarationWithTwoVariablesAtRight() { doStatementTest(" c, d := <selection>asd()</selection>", "interface{}, interface{}; interface{}"); } public void testVarDeclaration() { doStatementTest(" var a int = <selection>asd()</selection>", "int"); } public void testVarDeclarationWithStructTypeAndTwoVariablesAtRight() { doStatementTest(" var a, b struct{i int} = <selection>asd()</selection>", "struct{i int}, struct{i int}; struct{i int}"); } public void testVarDeclWithTwoMembersAtRightAndLeft() { doStatementTest(" var a, b struct{i int} = struct{i int} {1}, <selection>asd()</selection>", "struct{i int}"); } public void testCall() { doTopLevelTest(" func f(string){}; func _() { f(<selection>asd()</selection>) }", "string"); } public void testCallWithThreeParametersInReceiver() { doTopLevelTest(" func f(string, int, int){}; func _() { f(<selection>asd()</selection>) }", "string, int, int; string"); } public void testCallWithTwoArgumentsAndThreeParametersInReceiver() { doTopLevelTest(" func f(string, int, int){}; func _() { f(\"\", <selection>asd()</selection>) }", "int"); } public void testCallWithNoParametersInReceiver() { doTopLevelTest(" func f(){}; func _() { f(<selection>asd()</selection>) }", "interface{}"); } public void testCallWithNoParametersInReceiverAndThreeArguments() { doTopLevelTest(" func f(){}; func _() { f(1, 2, <selection>asd()</selection>) }", "interface{}"); } public void testCallWithOneExpectedType() { doTopLevelTest(" func f(int, int){}; func _() { f(1, <selection>asd()</selection>) }", "int"); } public void testCallWithParamDefinition() { doTopLevelTest(" func f(i, j int, string, int){}; func _() { f(<selection>asd()</selection>) }", "int, int, string, int; int"); } public void testRange() { doStatementTest("for _ = range <selection>asd()</selection> {}", "interface{}"); } public void testRangeWithTwoArguments() { doStatementTest("for _, _ = range <selection>asd()</selection> {}", "interface{}"); } public void testCaseStatement() { doStatementTest("var k int; switch k { case <selection>asd()</selection>: }", "int"); } public void testCaseStatementWithoutArg() { doStatementTest("var k int; switch { case <selection>asd()</selection>: }", "bool"); } public void testCaseStatementOnStatementAndExpr() { doStatementTest("var k int; switch q:=1; q { case <selection>asd()</selection>: }", "int"); } public void testSendStatementArg() { doStatementTest("var ch chan int; ch <- <selection>asd()</selection>", "int"); } public void testSendStatementChan() { doStatementTest("var i string; <selection>asd()</selection> <- i", "chan string"); } public void testSendStatementArgInSelect() { doStatementTest("var ch chan int; select { case ch <- <selection>asd()</selection> : }", "int"); } public void testSendUnaryOperation() { doStatementTest("var i int; i = <-<selection>asd()</selection>", "chan int"); } public void testSendUnaryOperationVarSpec() { doStatementTest("i := <-<selection>asd()</selection>", "chan interface{}"); } public void testSendUnaryOperationNoExpectedType() { doStatementTest(" <-<selection>asd()</selection>", "chan interface{}"); } public void testRecvStatement() { doStatementTest("var i string; select { case <-<selection>asd()</selection> : }", "chan interface{}"); } public void testRecvStatementOnFunc() { doStatementTest("var i string; select { case <selection>asd()</selection> : }", "interface{}"); } public void testRecvStatementOnVarAssign() { doStatementTest("var i string; select { case i = <selection>asd()</selection> : }", "string"); } public void testRecvStatementOnShortVarAssign() { doStatementTest("select { case i := <selection>asd()</selection> : }", "interface{}"); } private void doTopLevelTest(@NotNull String text, @NotNull String expectedTypeText) { myFixture.configureByText("a.go", "package a;" + text); PsiElement elementAt = findElementAtCaretOrInSelection(); GoExpression typeOwner = PsiTreeUtil.getNonStrictParentOfType(elementAt, GoExpression.class); assertNotNull("Cannot find type owner. Context element: " + elementAt.getText(), typeOwner); assertEquals(expectedTypeText, StringUtil.join(GoTypeUtil.getExpectedTypes(typeOwner), PsiElement::getText, "; ")); } private void doStatementTest(@NotNull String text, @NotNull String expectedTypeText) { doTopLevelTest("func _() {\n" + text + "\n}", expectedTypeText); } }