@NotNull @Override public PsiParameterList createParameterList( @NotNull final String[] names, @NotNull final PsiType[] types) throws IncorrectOperationException { @NonNls StringBuilder builder = new StringBuilder(); builder.append("void method("); for (int i = 0; i < names.length; i++) { if (i > 0) builder.append(", "); builder.append(types[i].getCanonicalText()).append(' ').append(names[i]); } builder.append(");"); return createMethodFromText(builder.toString(), null).getParameterList(); }
@NotNull @Override public PsiTypeParameter createTypeParameter(String name, PsiClassType[] superTypes) { @NonNls StringBuilder builder = new StringBuilder(); builder.append("public <").append(name); if (superTypes.length > 1 || superTypes.length == 1 && !superTypes[0].equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) { builder.append(" extends "); for (PsiClassType type : superTypes) { if (type.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) continue; builder.append(type.getCanonicalText()).append('&'); } builder.delete(builder.length() - 1, builder.length()); } builder.append("> void foo(){}"); try { return createMethodFromText(builder.toString(), null).getTypeParameters()[0]; } catch (RuntimeException e) { throw new IncorrectOperationException("type parameter text: " + builder.toString()); } }
@NotNull @Override public PsiDocTag createParamTag( @NotNull final String parameterName, @NonNls final String description) throws IncorrectOperationException { @NonNls final StringBuilder builder = new StringBuilder(); builder.append(" * @param "); builder.append(parameterName); builder.append(" "); final String[] strings = description.split("\\n"); for (int i = 0; i < strings.length; i++) { if (i > 0) builder.append("\n * "); builder.append(strings[i]); } return createDocTagFromText(builder.toString()); }
@NotNull @Override public PsiReferenceList createReferenceList( @NotNull final PsiJavaCodeReferenceElement[] references) throws IncorrectOperationException { @NonNls final StringBuilder builder = new StringBuilder(); builder.append("void method()"); if (references.length > 0) { builder.append(" throws "); for (int i = 0; i < references.length; i++) { if (i > 0) builder.append(", "); builder.append(references[i].getCanonicalText()); } } builder.append(';'); return createMethodFromText(builder.toString(), null).getThrowsList(); }
@Override public void endElement(String uri, String localName, String qName) throws SAXException { if ("item".equals(qName)) { externalName = null; } else if ("annotation".equals(qName)) { if (externalName != null && annotationFQN != null) { String argumentsString = arguments.length() == 0 ? "" : intern(arguments.toString()); for (AnnotationData existingData : data.get(externalName)) { if (existingData.annotationClassFqName.equals(annotationFQN)) { duplicateError(file, externalName, "Duplicate annotation '" + annotationFQN + "' "); } } AnnotationData annData = internAnnotationData(new AnnotationData(annotationFQN, argumentsString)); data.add(externalName, annData); annotationFQN = null; arguments = null; } } }
// This method is used for legacy reasons. // Old external annotations sometimes are bad XML: they have "<" and ">" characters in attributes // values. To prevent SAX parser from // failing, we escape attributes values. @NotNull private static String escapeAttributes(@NotNull String invalidXml) { // We assume that XML has single- and double-quote characters only for attribute values, // therefore we don't any complex parsing, // just have binary inAttribute state StringBuilder buf = new StringBuilder(invalidXml.length()); boolean inAttribute = false; for (int i = 0; i < invalidXml.length(); i++) { char c = invalidXml.charAt(i); if (inAttribute && c == '<') { buf.append("<"); } else if (inAttribute && c == '>') { buf.append(">"); } else if (c == '\"' || c == '\'') { buf.append('\"'); inAttribute = !inAttribute; } else { buf.append(c); } } return buf.toString(); }