/* * Copyright 2017 The Bazel Authors. All rights reserved. * * 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.google.idea.blaze.cpp.navigation; import com.google.idea.blaze.cpp.PartnerFilePatterns; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; import com.jetbrains.cidr.lang.psi.OCFile; import java.io.File; import javax.annotation.Nullable; class SwitchToHeaderOrSourceSearch { private SwitchToHeaderOrSourceSearch() {} @Nullable static OCFile getCorrespondingFile(OCFile file) { OCFile target = file.getAssociatedFileWithSameName(); if (target == null && !file.isHeader() && file.getVirtualFile() != null) { target = correlateTestToHeader(file); } return target; } @Nullable private static OCFile correlateTestToHeader(OCFile file) { // Quickly check foo_test.cc -> foo.h as well. "getAssociatedFileWithSameName" only does // foo.cc <-> foo.h. However, if you do goto-related-symbol again, it will go from // foo.h -> foo.cc instead of back to foo_test.cc. PsiManager psiManager = PsiManager.getInstance(file.getProject()); String pathWithoutExtension = FileUtil.getNameWithoutExtension(file.getVirtualFile().getPath()); for (String testSuffix : PartnerFilePatterns.DEFAULT_PARTNER_SUFFIXES) { if (pathWithoutExtension.endsWith(testSuffix)) { String possibleHeaderName = StringUtil.trimEnd(pathWithoutExtension, testSuffix) + ".h"; VirtualFile virtualFile = VfsUtil.findFileByIoFile(new File(possibleHeaderName), false); if (virtualFile != null) { PsiFile psiFile = psiManager.findFile(virtualFile); if (psiFile instanceof OCFile) { return (OCFile) psiFile; } } } } return null; } }