/* * Copyright 2013-2016 consulo.io * * 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 consulo.unity3d.csharp.codeInsight; import java.util.Map; import javax.swing.Icon; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import com.intellij.codeHighlighting.Pass; import com.intellij.codeInsight.daemon.LineMarkerInfo; import com.intellij.codeInsight.daemon.LineMarkerProviderDescriptor; import com.intellij.openapi.editor.markup.GutterIconRenderer; import com.intellij.openapi.module.ModuleUtilCore; import com.intellij.psi.PsiElement; import com.intellij.util.ConstantFunction; import consulo.annotations.RequiredReadAction; import consulo.csharp.ide.lineMarkerProvider.CSharpLineMarkerUtil; import consulo.csharp.lang.psi.CSharpMethodDeclaration; import consulo.csharp.lang.psi.CSharpTypeDeclaration; import consulo.csharp.lang.psi.impl.CSharpTypeUtil; import consulo.dotnet.psi.DotNetInheritUtil; import consulo.dotnet.psi.DotNetParameter; import consulo.dotnet.psi.DotNetParameterListOwner; import consulo.dotnet.psi.DotNetTypeDeclaration; import consulo.dotnet.resolve.DotNetTypeRef; import consulo.unity3d.Unity3dIcons; import consulo.unity3d.csharp.UnityFunctionManager; import consulo.unity3d.module.Unity3dModuleExtension; /** * @author VISTALL * @since 19.12.14 */ public class UnityEventCSharpMethodLineMarkerProvider extends LineMarkerProviderDescriptor { @Nullable @Override public String getName() { return "Unity C# Event Method"; } @Nullable @Override public Icon getIcon() { return Unity3dIcons.EventMethod; } @RequiredReadAction @Nullable @Override public LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement element) { return createMarker(element); } @Nullable @RequiredReadAction private static LineMarkerInfo createMarker(final PsiElement element) { CSharpMethodDeclaration methodDeclaration = CSharpLineMarkerUtil.getNameIdentifierAs(element, CSharpMethodDeclaration.class); if(methodDeclaration != null) { Unity3dModuleExtension extension = ModuleUtilCore.getExtension(element, Unity3dModuleExtension.class); if(extension == null) { return null; } PsiElement maybeTypeDeclaration = methodDeclaration.getParent(); if(maybeTypeDeclaration instanceof CSharpTypeDeclaration) { UnityFunctionManager functionManager = UnityFunctionManager.getInstance(); for(Map.Entry<String, Map<String, UnityFunctionManager.FunctionInfo>> entry : functionManager.getFunctionsByType().entrySet()) { UnityFunctionManager.FunctionInfo functionInfo = entry.getValue().get(element.getText()); if(functionInfo == null) { continue; } String typeName = entry.getKey(); if(DotNetInheritUtil.isParent(typeName, (DotNetTypeDeclaration) maybeTypeDeclaration, true)) { if(!isEqualParameters(functionInfo.getParameters(), methodDeclaration)) { return null; } return new LineMarkerInfo<>(element, element.getTextRange(), Unity3dIcons.EventMethod, Pass.LINE_MARKERS, new ConstantFunction<>(functionInfo.getDescription()), null, GutterIconRenderer.Alignment.LEFT); } } } } return null; } @RequiredReadAction private static boolean isEqualParameters(Map<String, String> funcParameters, DotNetParameterListOwner parameterListOwner) { DotNetParameter[] parameters = parameterListOwner.getParameters(); if(parameters.length == 0) { return true; } if(parameters.length != funcParameters.size()) { return false; } int i = 0; for(String expectedType : funcParameters.values()) { DotNetParameter parameter = parameters[i++]; DotNetTypeRef typeRef = UnityFunctionManager.createTypeRef(parameter, expectedType); if(!CSharpTypeUtil.isTypeEqual(parameter.toTypeRef(true), typeRef, parameter)) { return false; } } return true; } }