/* * Copyright 2000-2013 JetBrains s.r.o. * Copyright 2014-2014 AS3Boyan * Copyright 2014-2014 Elias Ku * * 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.intellij.plugins.haxe.lang.psi; import com.intellij.psi.PsiElement; import com.intellij.psi.util.PsiTreeUtil; import gnu.trove.THashMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Map; /** * @author: Fedor.Korotkov */ public class HaxeGenericSpecialization implements Cloneable { public static final HaxeGenericSpecialization EMPTY = new HaxeGenericSpecialization(); final Map<String, HaxeClassResolveResult> map; public HaxeGenericSpecialization() { this(new THashMap<String, HaxeClassResolveResult>()); } @Override protected HaxeGenericSpecialization clone() { final Map<String, HaxeClassResolveResult> clonedMap = new THashMap<String, HaxeClassResolveResult>(); for (String key : map.keySet()) { clonedMap.put(key, map.get(key)); } return new HaxeGenericSpecialization(clonedMap); } protected HaxeGenericSpecialization(Map<String, HaxeClassResolveResult> map) { this.map = map; } public void put(PsiElement element, String genericName, HaxeClassResolveResult resolveResult) { map.put(getGenericKey(element, genericName), resolveResult); } public boolean containsKey(@Nullable PsiElement element, String genericName) { return map.containsKey(getGenericKey(element, genericName)); } public HaxeClassResolveResult get(@Nullable PsiElement element, String genericName) { return map.get(getGenericKey(element, genericName)); } public HaxeGenericSpecialization getInnerSpecialization(PsiElement element) { final String prefixToRemove = getGenericKey(element, ""); final Map<String, HaxeClassResolveResult> result = new THashMap<String, HaxeClassResolveResult>(); for (String key : map.keySet()) { final HaxeClassResolveResult value = map.get(key); String newKey = key; if (newKey.startsWith(prefixToRemove)) { newKey = newKey.substring(prefixToRemove.length()); } result.put(newKey, value); } return new HaxeGenericSpecialization(result); } public static String getGenericKey(@Nullable PsiElement element, @NotNull String genericName) { final StringBuilder result = new StringBuilder(); final HaxeNamedComponent namedComponent = PsiTreeUtil.getParentOfType(element, HaxeNamedComponent.class, false); if (namedComponent instanceof HaxeClass) { result.append(((HaxeClass)namedComponent).getQualifiedName()); } else if (namedComponent != null) { HaxeClass haxeClass = PsiTreeUtil.getParentOfType(namedComponent, HaxeClass.class); if (haxeClass instanceof HaxeAnonymousType) { // class -> typeOrAnonymous -> anonymous final PsiElement parent = haxeClass.getParent().getParent(); haxeClass = parent instanceof HaxeClass ? (HaxeClass)parent : haxeClass; } if (haxeClass != null) { result.append(haxeClass.getQualifiedName()); } if (PsiTreeUtil.getChildOfType(namedComponent, HaxeGenericParam.class) != null) { // generic method result.append(":"); result.append(namedComponent.getName()); } } if (result.length() > 0) { result.append("-"); } result.append(genericName); return result.toString(); } public String debugDump() { return debugDump(null); } public String debugDump( String linePrefix ) { StringBuilder builder = new StringBuilder(); if (linePrefix == null) { linePrefix = ""; } builder.append(linePrefix); builder.append(getClass().getName()); builder.append(" : size="); builder.append(map.size()); builder.append("\n"); String prefix = linePrefix + " "; for (String key : map.keySet()) { builder.append(prefix); builder.append(key); builder.append(" -> "); HaxeClassResolveResult result = map.get(key); builder.append(result == null ? "<no value>\n" : result.debugDump(prefix)); } return builder.toString(); } }