package com.intellij.lang.javascript.flex.importer; import com.intellij.lang.actionscript.psi.stubs.impl.ActionScriptFunctionStubImpl; import com.intellij.lang.actionscript.psi.stubs.impl.ActionScriptVariableStubImpl; import com.intellij.lang.javascript.JSStubElementTypes; import com.intellij.lang.javascript.psi.JSFunction; import com.intellij.lang.javascript.psi.ecmal4.JSAttributeList; import com.intellij.lang.javascript.psi.ecmal4.JSReferenceList; import com.intellij.lang.javascript.psi.stubs.JSReferenceListStub; import com.intellij.lang.javascript.psi.stubs.impl.*; import com.intellij.lang.javascript.psi.types.JSContext; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.stubs.StubElement; import com.intellij.util.SmartList; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.LinkedList; import java.util.List; import java.util.StringTokenizer; class AS3InterfaceStubDumper extends AS3InterfaceDumper { final LinkedList<StubElement> parents; private static final JSAttributeList.AccessType[] ourAccessTypes = JSAttributeList.AccessType.values(); private static final JSAttributeList.ModifierType[] ourModifierTypes = JSAttributeList.ModifierType.values(); public AS3InterfaceStubDumper(StubElement parent) { parents = new LinkedList<>(); parents.add(parent); } @Override public void processMetadata(MetaData metaData) { parents.addLast(new JSAttributeStubImpl(metaData.name, parents.getLast())); super.processMetadata(metaData); parents.removeLast(); } @Override public void addMetaDataValue(String s, String s1) { new JSAttributeNameValuePairStubImpl(s, StringUtil.stripQuotesAroundValue(s1), parents.getLast()); } @Override protected void processArgumentList(MethodInfo methodInfo, String parentName) { parents.add(new JSParameterListStubImpl(parents.getLast(), JSStubElementTypes.PARAMETER_LIST)); super.processArgumentList(methodInfo, parentName); parents.removeLast(); } @Override public void processParameter(@NotNull String name, @Nullable Multiname type, String parentName, @Nullable Multiname value, boolean rest) { new JSParameterStubImpl( name, rest, getTypeRef(type, parentName), getValueRepr(value), parents.getLast() ); } @Override public void append(@NotNull @NonNls String str) {} @Override public void processFunction(MethodInfo methodInfo, boolean referenceNameRequested, Abc abc, String indent, String attr) { parents.add( new ActionScriptFunctionStubImpl( methodInfo.name.name, methodInfo.isGetMethod() ? JSFunction.FunctionKind.GETTER : methodInfo.isSetMethod() ? JSFunction.FunctionKind.SETTER : methodInfo.parentTraits != null && methodInfo.parentTraits.name == methodInfo.name ? JSFunction.FunctionKind.CONSTRUCTOR : JSFunction.FunctionKind.SIMPLE, getMultinameAsPackageName(methodInfo.name,methodInfo.parentTraits != null ? methodInfo.parentTraits.getClassName():null), getTypeRef(methodInfo.returnType, methodInfo.getParentName()), "static ".equals(attr) ? JSContext.STATIC : JSContext.INSTANCE, getAccessType(methodInfo), parents.getLast() ) ); super.processFunction(methodInfo, referenceNameRequested, abc, indent, attr); parents.removeLast(); } @Override public void processVariable(SlotInfo info, String indent, String attr) { parents.add(new JSVarStatementStubImpl(parents.getLast(), JSStubElementTypes.VAR_STATEMENT)); super.processVariable(info, indent, attr); String parentName = info.getParentName(); String qName = getMultinameAsPackageName(info.name, parentName); new ActionScriptVariableStubImpl( qName.substring(qName.lastIndexOf('.') + 1), info.isConst(), getTypeRef(info.type, parentName), getValueRepr(info.value), qName, "static ".equals(attr) ? JSContext.STATIC : JSContext.INSTANCE, getAccessType(info), parents.getLast() ); parents.removeLast(); } @Override public void processClass(SlotInfo slotInfo, Abc abc, String attr, String indent) { parents.add( new ActionScriptClassStubImpl( slotInfo.name.name, slotInfo.isInterfaceClass(), getMultinameAsPackageName(slotInfo.name, null), getAccessType(slotInfo), parents.getLast() ) ); super.processClass(slotInfo, abc, attr, indent); parents.removeLast(); } @NotNull private JSAttributeList.AccessType getAccessType(MemberInfo memberInfo) { final String nsName = memberInfo.name.getNsName(memberInfo); JSAttributeList.AccessType accessType = JSAttributeList.AccessType.PACKAGE_LOCAL; if ("public".equals(nsName)) accessType = JSAttributeList.AccessType.PUBLIC; else if ("protected".equals(nsName)) accessType = JSAttributeList.AccessType.PROTECTED; else if ("private".equals(nsName)) accessType = JSAttributeList.AccessType.PRIVATE; else if ("internal".equals(nsName)) accessType = JSAttributeList.AccessType.PACKAGE_LOCAL; return accessType; } @Override protected void processModifierList(MemberInfo memberInfo, String attr, String indent) { StringTokenizer tokenizer = new StringTokenizer(attr, " "); List<JSAttributeList.ModifierType> modifiers = new SmartList<>(); JSAttributeList.AccessType accessType = null; String ns = null; while(tokenizer.hasMoreTokens()) { String next = tokenizer.nextToken(); boolean foundModifier = false; for(JSAttributeList.AccessType type: ourAccessTypes) { if (next.equalsIgnoreCase(type.name())) { accessType = type; foundModifier = true; break; } } if (!foundModifier) { for(JSAttributeList.ModifierType type: ourModifierTypes) { if (next.equalsIgnoreCase(type.name())) { modifiers.add(type); foundModifier = true; break; } } } if (!foundModifier) ns = next; } Traits parentTraits = memberInfo.parentTraits; if (parentTraits.staticTrait != null) { parentTraits = parentTraits.staticTrait; } String resolvedNs = null; if (parentTraits.usedNamespacesToNamesMap != null) { List<String> keysByValue = parentTraits.usedNamespacesToNamesMap.getKeysByValue(ns); resolvedNs = keysByValue != null && keysByValue.size() > 0 ? keysByValue.get(0) : null; } parents.add(new ActionScriptAttributeListStubImpl(parents.getLast(), ns, resolvedNs, accessType, modifiers.toArray(new JSAttributeList.ModifierType[modifiers.size()]))); super.processModifierList(memberInfo, attr, indent); parents.removeLast(); } @Override protected void dumpExtendsList(Traits it) { if (!it.base.isStarReference()) { String ref = getTypeRef(it.base, null); JSReferenceListStub<JSReferenceList> parent = JSStubElementTypes.DEFAULT_EXTENDS_LIST.createStub(parents.getLast()); new JSReferenceListMemberStubImpl(parent, ref); } } @Override protected void dumpInterfacesList(String indent, Traits it, boolean anInterface) { if (it.interfaces.length > 0) { JSReferenceListStubImpl parent = new JSReferenceListStubImpl(parents.getLast(), anInterface ? JSStubElementTypes.DEFAULT_EXTENDS_LIST : JSStubElementTypes.IMPLEMENTS_LIST); for (Multiname name : it.interfaces) { new JSReferenceListMemberStubImpl(parent, getTypeRef(name, null)); } } } }