/* * 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.GoCodeInsightFixtureTestCase; import com.goide.SdkAware; import com.goide.codeInsight.imports.GoImportOptimizerTest; import com.goide.inspections.unresolved.*; import com.goide.project.GoModuleLibrariesService; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiDirectory; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiReference; import org.jetbrains.annotations.NotNull; import java.io.IOException; @SdkAware public class GoHighlightingTest extends GoCodeInsightFixtureTestCase { @Override public void setUp() throws Exception { super.setUp(); myFixture.enableInspections( GoUnresolvedReferenceInspection.class, GoDuplicateFieldsOrMethodsInspection.class, GoUnusedImportInspection.class, GoUnusedVariableInspection.class, GoUnusedConstInspection.class, GoUnusedGlobalVariableInspection.class, GoUnusedFunctionInspection.class, GoUnusedExportedFunctionInspection.class, GoAssignmentToConstantInspection.class, GoDuplicateFunctionOrMethodInspection.class, GoDuplicateArgumentInspection.class, GoDuplicateReturnArgumentInspection.class, GoFunctionVariadicParameterInspection.class, GoVarDeclarationInspection.class, GoNoNewVariablesInspection.class, GoMissingReturnInspection.class, GoFunctionCallInspection.class, GoDeferGoInspection.class, GoReservedWordUsedAsNameInspection.class, GoImportUsedAsNameInspection.class, GoMultiplePackagesInspection.class, GoCgoInTestInspection.class, GoTestSignaturesInspection.class, GoAssignmentNilWithoutExplicitTypeInspection.class, GoRedeclareImportAsFunctionInspection.class, GoStructTagInspection.class, GoUsedAsValueInCondition.class, GoDeferInLoopInspection.class, GoCommentStartInspection.class, GoPlaceholderCountInspection.class, GoEmbeddedInterfacePointerInspection.class, GoUnderscoreUsedAsValueInspection.class, GoRangeIterationOnIllegalTypeInspection.class, GoUnusedParameterInspection.class, GoDirectAssignToStructFieldInMapInspection.class, GoInfiniteForInspection.class, GoAssignmentToReceiverInspection.class, GoInvalidStringOrCharInspection.class, GoMixedNamedUnnamedParametersInspection.class, GoAnonymousFieldDefinitionTypeInspection.class, GoStringAndByteTypeMismatchInspection.class ); } private void doTest() { myFixture.testHighlighting(true, false, false, getTestName(true) + ".go"); } @NotNull @Override protected String getBasePath() { return "highlighting"; } @Override protected boolean isWriteActionRequired() { return false; } public void testSimple() { doTest(); } public void testLabels() { doTest(); } public void testStruct() { doTest(); } public void testBoxes() { doTest(); } public void testRanges() { doTest(); } public void testSelector() { doTest(); } public void testComposite() { doTest(); } public void testVars() { doTest(); } public void testRecv() { doTest(); } public void testPointers() { doTest(); } public void testSlices() { doTest(); } public void testShortVars() { doTest(); } public void testReturns() { doTest(); } public void testRequest() { doTest(); } public void testStop() { doTest(); } public void testVarBlocks() { doTest(); } public void testBlankImport() { doTest(); } public void testVariadic() { doTest(); } public void testCheck() { doTest(); } public void testCheck_test() { doTest(); } public void testFuncCall() { doTest(); } public void testBuiltinFuncCalls() { doTest(); } public void testBackticks() { doTest(); } public void testConsts() { doTest(); } public void testFields() { doTest(); } public void testBlankFields() { doTest(); } public void testFuncLiteral() { doTest(); } public void testTypeLiterals() { doTest(); } public void testFuncType() { doTest(); } public void testTemplates() { doTest(); } public void testInterfaces() { doTest(); } public void testReceiverType() { doTest(); } public void testForRange() { doTest(); } public void testMismatch() { doTest(); } public void testStubParams() { doTest(); } public void testNil() { doTest(); } public void testAssignUsages() { doTest(); } public void testMethodExpr() { doTest(); } public void testVarToImport() { doTest(); } public void testCgotest() { doTest(); } public void testRedeclaredImportAsFunction(){ doTest(); } public void testStructTags() { doTest(); } public void testContinue() { doTest(); } public void testBreak() { doTest(); } public void testEqualinif() { doTest(); } public void testSpecTypes() { doTest(); } public void testFunctionTypes() { doTest(); } public void testGithubIssue2099() { doTest(); } public void testCyclicDefinition() { doTest(); } public void testEmbeddedInterfacePointer() { doTest(); } public void testPlaceholderCount() { doTest(); } public void testPlaceholderCountVet() { doTest(); } public void testTypeConversion() { doTest(); } public void testInit() { doTest(); } public void testMainWithWrongSignature() { doTest(); } public void testChan() { doTest(); } public void testIota() { doTest(); } public void testIota2() { doTest(); } public void testUnaryPointer() { doTest(); } public void testUnaryMinus() { doTest(); } public void testFileRead() { doTest(); } public void testLiteralValues() { doTest(); } public void testUnderscoreUsedAsValue() { doTest(); } public void testUnusedParameter() { doTest(); } public void testUnusedParameter_test() { doTest(); } public void testVoidFunctionUsedAsValue() { doTest(); } public void testIndexedStringAssign() { doTest(); } public void testStringSliceWithThirdIndex() { doTest(); } public void testSliceWithThirdIndex() { doTest(); } public void testAssignToStructFieldInMap() { doTest(); } public void testInfiniteFor() { doTest(); } public void testGh2147() { doTest(); } public void testAssignmentToReceiver() { doTest(); } public void testReservedWordUsedAsName() { doTest(); } public void testImportUsedAsName() { doTest(); } public void testMixedNamedUnnamedParameters() { doTest(); } public void testStringInStructSliceWithThirdIndex() { doTest(); } public void testAnonymousFieldDefinition() { doTest(); } public void testStringIndexIsByte() { doTest(); } public void testCodedImportString() { myFixture.addFileToProject("a/a.go", "package a\n const A = 3"); PsiFile file = myFixture.addFileToProject("b/b.go", "package b\n import \"\\u0061\" \n" + "const <warning descr=\"Unused constant 'my'\">my</warning> = a.A"); myFixture.configureFromExistingVirtualFile(file.getVirtualFile()); myFixture.checkHighlighting(); } public void testDoNotResolveReceiverTypeToFunction() { myFixture.addFileToProject("pack1/a.go", "package foo; func functionInCurrentPackage() {}"); PsiFile file = myFixture.addFileToProject("pack1/b.go", "package foo; func (<error descr=\"Unresolved type 'functionInCurrentPackage'\">functionInCurrentPackage</error>) method() {}"); myFixture.configureFromExistingVirtualFile(file.getVirtualFile()); myFixture.checkHighlighting(); } public void testAvoidDuplicatedUnusedImportReports() { myFixture.addFileToProject("pack1/a.go", "package foo;"); myFixture.addFileToProject("pack1/b.go", "package foo_test;"); myFixture.addFileToProject("pack2/a.go", "package foo;"); myFixture.addFileToProject("pack3/a.go", "package foo; func Hi() {}"); doTest(); } public void testCheckSamePackage_test() { myFixture.configureByText("a_test.go", "package check; func TestStringer(t *testing.T) {}"); doTest(); } public void testRelativeImportIgnoringDirectories() throws IOException { myFixture.getTempDirFixture().findOrCreateDir("to_import/testdata"); myFixture.getTempDirFixture().findOrCreateDir("to_import/.name"); myFixture.getTempDirFixture().findOrCreateDir("to_import/_name"); doTest(); } public void testImportWithSlashAtTheEnd() { myFixture.addFileToProject("a/pack/pack.go", "package pack; func Foo() {}"); PsiFile file = myFixture.addFileToProject("pack2/pack2.go", "package main; import \"a/pack/<error descr=\"Cannot resolve file ''\"></error>\"; import \"../a/pack/\"; func main() { pack.Foo() }"); myFixture.configureFromExistingVirtualFile(file.getVirtualFile()); myFixture.checkHighlighting(); } @SuppressWarnings("ConstantConditions") public void testDoNotReportNonLastMultiResolvedImport() { myFixture.addFileToProject("root1/src/to_import/unique/foo.go", "package unique; func Foo() {}"); myFixture.addFileToProject("root1/src/to_import/shared/a.go", "package shared"); myFixture.addFileToProject("root2/src/to_import/shared/a.go", "package shared"); GoModuleLibrariesService.getInstance(myFixture.getModule()).setLibraryRootUrls(myFixture.findFileInTempDir("root1").getUrl(), myFixture.findFileInTempDir("root2").getUrl()); doTest(); PsiReference reference = myFixture.getFile().findReferenceAt(myFixture.getCaretOffset()); PsiElement resolve = reference.resolve(); assertInstanceOf(resolve, PsiDirectory.class); assertTrue(((PsiDirectory)resolve).getVirtualFile().getPath().endsWith("root1/src/to_import/shared")); GoModuleLibrariesService.getInstance(myFixture.getModule()).setLibraryRootUrls(myFixture.findFileInTempDir("root2").getUrl(), myFixture.findFileInTempDir("root1").getUrl()); reference = myFixture.getFile().findReferenceAt(myFixture.getCaretOffset()); resolve = reference.resolve(); assertInstanceOf(resolve, PsiDirectory.class); assertTrue(((PsiDirectory)resolve).getVirtualFile().getPath().endsWith("root2/src/to_import/shared")); } public void testLocalScope() { myFixture.configureByText("a.go", "package foo; func bar() {}"); myFixture.configureByText("b.go", "package foo; func init(){bar()}"); myFixture.checkHighlighting(); } public void testInnerTypesFromOtherPackage() { myFixture.configureByText("main.go", "package main; import \"io\"; type Outer struct { *io.LimitedReader };" + "func main() { _ = &Outer{LimitedReader: &io.LimitedReader{}, } }"); myFixture.checkHighlighting(); } public void testNoLocalResolveForTest() { myFixture.configureByText("a.go", "package i; type P struct { v1 int }"); myFixture .configureByText("b_test.go", "package i_test; import ( \".\" ); func <warning>f</warning>() { print(i.P{}.<error>v1</error>) }"); myFixture.checkHighlighting(); } public void testDuplicateFunctionsInOnePackage() { myFixture.configureByText("a.go", "package foo; func init() {bar()}; func bar() {};"); myFixture.configureByText("b.go", "//+build appengine\n\npackage foo; func init() {buzz()}; func buzz() {}"); myFixture.configureByText("c.go", "package foo; func init() {bar(); buzz();}; func <error descr=\"Duplicate function name\">bar</error>() {}; func buzz() {}"); myFixture.checkHighlighting(); } public void testDuplicateFunctionsInDifferentPackages() { myFixture.configureByText("a.go", "package foo; func init() {bar()}; func bar() {};"); myFixture.configureByText("b_test.go", "package foo_test; func init() {bar(); buzz();}; func bar() {}; func buzz() {}"); myFixture.checkHighlighting(); } public void testDoNotSearchFunctionDuplicatesForNotTargetMatchingFiles() { myFixture.configureByText("a.go", "//+build appengine\n\npackage foo; func init() {buzz()}; func buzz() {}"); myFixture.configureByText("b.go", "package foo; func init() {buzz()}; func buzz() {}"); myFixture.checkHighlighting(); } public void testDuplicateMethodsInOnePackage() { myFixture.configureByText("a.go", "package main; type Foo int; func (f Foo) bar(a, b string) {}"); myFixture.configureByText("b.go", "//+build appengine\n\npackage main; func (a *Foo) bar() {};func (a *Foo) buzz() {}"); myFixture.configureByText("c.go", "package main; func (a *Foo) <error>bar</error>() {};func (a *Foo) buzz() {}"); myFixture.checkHighlighting(); } public void testDoNotSearchMethodDuplicatesForNotTargetMatchingFiles() { myFixture.configureByText("b.go", "//+build appengine\n\npackage main; func (a *Foo) bar() {}"); myFixture.configureByText("a.go", "package main; type Foo int; func (f Foo) bar(_, _ string) {}"); myFixture.checkHighlighting(); } public void testNoDuplicateMethodsInOnePackage() { myFixture.configureByText("a.go", "package main; type Foo int; func (f Foo) bar() {}"); myFixture.configureByText("b.go", "package main; type Baz int; func (f Baz) bar() {}"); myFixture.checkHighlighting(); } public void testInitInOnePackage() { myFixture.configureByText("a.go", "package foo; func init() {bar()}; func bar() {}"); myFixture.configureByText("b.go", "package foo; func init() {bar()}; func <error>bar</error>() {}; func init() {}"); myFixture.checkHighlighting(); } public void testMainInFooPackage() { myFixture.configureByText("a.go", "package foo; func main() {bar()}; func bar() {}"); myFixture.configureByText("b.go", "package foo; func <error>main</error>() {bar()}; func <error>bar</error>() {}"); myFixture.checkHighlighting(); } public void testMainInMainPackage() { myFixture.configureByText("a.go", "package main; func main() {bar()}; func bar() {}"); myFixture.configureByText("b.go", "package main; func main() {bar()}; func <error>bar</error>() {}"); myFixture.checkHighlighting(); } public void testUseNilWithoutExplicitType() { myFixture.configureByText("a.go", "package main; func main() { var x string = nil; _ = x; var y = <error>nil</error>; _ = y}"); myFixture.checkHighlighting(); } public void testPackageWithTestPrefix() { myFixture.addFileToProject("pack1/pack1_test.go", "package pack1_test; func Test() {}"); PsiFile file = myFixture.addFileToProject("pack2/pack2_test.go", "package pack2_test; import \"testing\"; func TestTest(*testing.T) {<error>pack1_test</error>.Test()}"); myFixture.configureFromExistingVirtualFile(file.getVirtualFile()); myFixture.checkHighlighting(); } public void testMethodOnNonLocalType() { VirtualFile file = myFixture.copyFileToProject(getTestName(true) + ".go", "method/nonlocaltype.go"); myFixture.configureFromExistingVirtualFile(file); GoImportOptimizerTest.resolveAllReferences(myFixture.getFile()); myFixture.checkHighlighting(); } public void testMethodOnNonLocalTypeInTheSameDirectory() { myFixture.addFileToProject("method/foo.go", "package a; type H struct {}"); PsiFile psiFile = myFixture.addFileToProject("method/foo_test.go", "package a_test;\n" + "func (<error descr=\"Unresolved type 'H'\">H</error>) Hello() {}"); myFixture.configureFromExistingVirtualFile(psiFile.getVirtualFile()); myFixture.checkHighlighting(); } public void testPackageWithTestPrefixNotInsideTestFile() { myFixture.addFileToProject("pack1/pack1.go", "package pack1_test; func Test() {}"); PsiFile file = myFixture.addFileToProject("pack2/pack2_test.go", "package pack2_test; import `pack1`; import \"testing\"; func TestTest(*testing.T) {pack1_test.Test()}"); myFixture.configureFromExistingVirtualFile(file.getVirtualFile()); myFixture.checkHighlighting(); } public void testBlankPackage() { myFixture.configureByText("a.go", "package <error descr=\"Invalid package name\">_</error>"); myFixture.checkHighlighting(); } public void testMultiplePackages() { myFixture.addFileToProject("a.go", "package a"); myFixture.configureByText("b.go", "<error>package b</error>"); myFixture.checkHighlighting(); } public void testMultiplePackagesWithIgnoredFile() { myFixture.addFileToProject("a.go", "// +build ignored\n\npackage a"); myFixture.addFileToProject(".c.go", "// package a"); myFixture.addFileToProject("_c.go", "// package a"); // Should be OK to have package b because package a has a non-matching // build tag. myFixture.configureByText("b.go", "package b"); myFixture.checkHighlighting(); } public void testMultiplePackagesWithDocumentationPackage() { myFixture.addFileToProject("a.go", "package documentation"); myFixture.configureByText("b.go", "package b"); myFixture.checkHighlighting(); } public void testDocumentationPackage() { myFixture.addFileToProject("a.go", "package a"); myFixture.configureByText("docs.go", "package documentation"); myFixture.checkHighlighting(); } public void testTestPackage() { myFixture.addFileToProject("a.go", "package a"); myFixture.configureByText("a_test.go", "package a_test"); myFixture.checkHighlighting(); } public void testCGOImportInTestFile() { myFixture.configureByText("a_test.go", "package a; import<error>\"C\"</error>; import<error>\"C\"</error>;"); myFixture.checkHighlighting(); } public void testDeferInLoop() { doWeakTest(); } public void testDeferGo() { doWeakTest(); } public void testCommentStart() { doWeakTest(); } private long doWeakTest() {return myFixture.testHighlighting(true, false, true, getTestName(true) + ".go");} public void testDoNotHighlightCommentOfMainPackage() { myFixture.configureByText("a.go", "// Some comment\npackage main; func main() {}"); myFixture.checkHighlighting(true, false, true); } public void testCGOImportInNonTestFile() { myFixture.configureByText("a.go", "package a; import \"C\""); myFixture.checkHighlighting(); } public void testVendoringImportPaths() { myFixture.addFileToProject("vendor/vendoringPackage/v.go", "package vendoringPackage; func Hello() {}"); myFixture.addFileToProject("subPackage/vendor/subVendoringPackage/v.go", "package subVendoringPackage; func Hello() {}"); doTest(); } public void testVendoredBuiltinImport() { myFixture.addFileToProject("vendor/builtin/builtin.go", "package builtin; func Hello() {}"); myFixture.configureByText("a.go", "package a; import _ `builtin`"); myFixture.checkHighlighting(); } public void testDuplicatePackageAlias() { myFixture.addFileToProject("pack1/pack1.go", "package pack1; func Foo() {}"); myFixture.addFileToProject("pack2/pack2.go", "package pack2"); PsiFile file = myFixture.addFileToProject("pack3/pack3.go", "package main; import p \"pack1\"; import <error>p \"pack2\"</error>; func main() { p.Foo() }"); myFixture.configureFromExistingVirtualFile(file.getVirtualFile()); myFixture.checkHighlighting(); } public void testDuplicatePackageImport() { myFixture.addFileToProject("pack/pack1.go", "package pack; func Foo() {}"); PsiFile file = myFixture.addFileToProject("pack3/pack3.go", "package main; import \"pack\"; import <error>\"pack\"</error>; func main() { pack.Foo() }"); myFixture.configureFromExistingVirtualFile(file.getVirtualFile()); myFixture.checkHighlighting(); } public void testDuplicateFinalPackageComponent() { myFixture.addFileToProject("a/pack/pack1.go", "package pack; func Foo() {}"); myFixture.addFileToProject("b/pack/pack2.go", "package pack"); PsiFile file = myFixture.addFileToProject("pack3/pack3.go", "package main; import \"a/pack\"\n" + "import <error>\"b/pack\"</error>\n" + "func main() { pack.Foo() }"); myFixture.configureFromExistingVirtualFile(file.getVirtualFile()); myFixture.checkHighlighting(); } public void testIgnoredBuildTag() { myFixture.addFileToProject("a/pack1.go", "package a; func Foo() {}"); myFixture.addFileToProject("a/pack2.go", "// +build ignored\n\npackage main"); myFixture.addFileToProject("b/pack1.go", "package b; func Bar() {}"); myFixture.addFileToProject("b/pack2.go", "// +build ignored\n\npackage main"); // There should be no errors: package main exists in the a/ and b/ // directories, but it is not imported as it has a non-matching build tag. // For more details see https://github.com/go-lang-plugin-org/go-lang-idea-plugin/issues/1858#issuecomment-139794391. PsiFile file = myFixture.addFileToProject("c/pack1.go", "package main; import \"a\"; import \"b\"; func main() { a.Foo(); b.Bar(); }"); myFixture.configureFromExistingVirtualFile(file.getVirtualFile()); myFixture.checkHighlighting(); } public void testImportUnderscore() { myFixture.addFileToProject("a/pack/pack1.go", "package pack; func Foo() {}"); myFixture.addFileToProject("b/pack/pack2.go", "package pack"); myFixture.addFileToProject("c/pack/pack3.go", "package whatever; func Bar() {}"); myFixture.addFileToProject("d/pack/pack4.go", "package another; func Baz() {}"); PsiFile file = myFixture.addFileToProject("pack3/pack3.go", "package main; import _ \"a/pack\"; import _ \"b/pack\"; import . \"c/pack\"; import . \"d/pack\"; func main() { Bar(); Baz() }"); myFixture.configureFromExistingVirtualFile(file.getVirtualFile()); myFixture.checkHighlighting(); } }