private void parseTypes2( Map<String, Collection<String>> map, Iterable<ArrayHashElement> elements, String parent) { Collection<String> types = map.get(parent); if (types == null) { types = new ArrayList<String>(); map.put(parent, types); } for (ArrayHashElement element : elements) { PhpPsiElement key = element.getKey(); if (key instanceof StringLiteralExpression) { // key String keyName = ((StringLiteralExpression) key).getContents(); types.add(keyName); String fullKeyName = parent.length() > 0 ? (parent + "." + keyName) : keyName; // value PhpPsiElement val = element.getValue(); if (val instanceof ArrayCreationExpression) { // recursive Iterable<ArrayHashElement> subElements = ((ArrayCreationExpression) val).getHashElements(); parseTypes2(map, subElements, fullKeyName); } else if (val instanceof FieldReference) { // reference to a field, where it's defined String classFqn = ((ClassReference) ((FieldReference) val).getClassReference()).getFQN(); for (PhpClass phpClass : PhpIndex.getInstance(element.getProject()).getClassesByFQN(classFqn)) { Field field = phpClass.findFieldByName(((FieldReference) val).getNameCS(), false); if (field.getDefaultValue() instanceof ArrayCreationExpression) { Iterable<ArrayHashElement> subElements = ((ArrayCreationExpression) field.getDefaultValue()).getHashElements(); parseTypes2(map, subElements, fullKeyName); } } } else { // get value type parseValueType(val); // try annotation PsiElement el2 = element; while (el2 != null && (el2 instanceof LeafPsiElement && ((LeafPsiElement) el2).getElementType() == PhpTokenTypes.opCOMMA || el2 instanceof PsiWhiteSpace)) { el2 = el2.getNextSibling(); } if (el2 instanceof PsiComment) { System.out.println("Comment for " + fullKeyName + ": " + el2.getText()); } } } } }