/* * 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.GoType; import com.goide.psi.GoTypeOwner; import com.intellij.psi.PsiElement; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; @SdkAware public class GoTypeResolveTest extends GoCodeInsightFixtureTestCase { public void testAnon() { doTopLevelTest("type A struct{};type E A;type B struct{ E };func (e E) foo() {};func main() { b := B{}; b.<caret>E }", "E"); } public void testAnon2() { doTopLevelTest("type A struct{};type E A;type B struct{ *E };func (e E) foo() {};func main() { b := B{}; b.<caret>E }", "*E"); } public void testTypeSwitchDeclaration() { doStatementTest("switch fo<caret>o := \"hello\".(type) {}", "string"); } public void testTypeSwitchUsageInContext() { doStatementTest("switch foo := \"hello\".(type) { case bool:\n println(fo<caret>o)\n}", "bool"); } public void testWrappedSlice() { doTopLevelTest("type Foo int[]\nfunc _() { var foo Foo\nb<caret>ar := foo[2:9]", "Foo"); } public void testSlice() { doStatementTest("var foo []int\nb<caret>ar := foo[2:9]", "[]int"); } public void testRangeOverString() { doStatementTest("for _, fo<caret>o := range \"hello\" {}", "int32"); } public void testIndexExpressionOfString() { doStatementTest("foo := \"hello\"\na := <selection>foo[0]</selection>", "byte"); } public void testIndexExpressionOfStringLiteral() { doExpressionTest("<selection>\"hello\"[0]</selection>", "byte"); } public void testIndexExpressionOfPointer() { doStatementTest("var buckhash *[20]*int\nfo<caret>o := buckhash[0]", "*int"); } public void testNestedTypeSwitchUsageInContext() { doStatementTest("var p interface{}\n" + "switch foo := p.(type) {\n" + "case int:\n" + " switch p.(type) {\n" + " case bool:" + " println(f<caret>oo)\n" + " }\n" + "}", "int"); } public void testIndexExpression() { doTopLevelTest("type foo string; var bar []foo; func _() { println(<selection>bar[0]</selection>) }", "foo"); doTopLevelTest("var bar []string; func _() { println(<selection>bar[0]</selection>) }", "string"); } public void testFuncLiteral() { doTopLevelTest("func voidFunction(a int) {} func _() { <selection>voidFunction</selection>() }", "func (a int)"); } public void testCallExpression() { doTopLevelTest("func voidFunction() int {} func _() { <selection>voidFunction()</selection> }", "int"); } public void testCallExpressionOnVoidFunction() { doTopLevelTest("func voidFunction() {} func _() { <selection>voidFunction()</selection> }", "<unknown>"); } public void testCallExpressionOnVoidFunction2() { doTopLevelTest("func voidFunction() () {} func _() { <selection>voidFunction()</selection> }", "<unknown>"); } private void doTopLevelTest(@NotNull String text, @NotNull String expectedTypeText) { myFixture.configureByText("a.go", "package a;" + text); PsiElement elementAt = findElementAtCaretOrInSelection(); GoTypeOwner typeOwner = PsiTreeUtil.getNonStrictParentOfType(elementAt, GoTypeOwner.class); assertNotNull("Cannot find type owner. Context element: " + elementAt.getText(), typeOwner); GoType type = typeOwner.getGoType(null); assertEquals(expectedTypeText, type == null ? "<unknown>" : type.getText()); } private void doStatementTest(@NotNull String text, @NotNull String expectedTypeText) { doTopLevelTest("func _() {\n" + text + "\n}", expectedTypeText); } private void doExpressionTest(@NotNull String text, @NotNull String expectedTypeText) { doStatementTest("a := " + text, expectedTypeText); } }