public static String parseClassOrTypeVariableElement(CharacterIterator signature) throws ClsFormatException { char variance = parseVariance(signature); if (variance == '*') { return decorateTypeText("*", variance); } int arrayCount = 0; while (signature.current() == '[') { arrayCount++; signature.next(); } final String type = parseTypeWithoutVariance(signature); if (type != null) { String ref = type; while (arrayCount > 0) { ref += "[]"; arrayCount--; } return decorateTypeText(ref, variance); } else { throw new ClsFormatException(); } }
@NotNull public static String parseTypeString(@NotNull CharacterIterator signature) throws ClsFormatException { int arrayDimensions = 0; while (signature.current() == '[') { arrayDimensions++; signature.next(); } char variance = parseVariance(signature); String text = parseTypeWithoutVariance(signature); if (text == null) throw new ClsFormatException(); for (int i = 0; i < arrayDimensions; i++) { text += "[]"; } if (variance != '\0') { text = variance + text; } return text; }
public static String parseTypeString(CharacterIterator signature) throws ClsFormatException { int arrayDimensions = 0; while (signature.current() == '[') { arrayDimensions++; signature.next(); } char variance = parseVariance(signature); @NonNls String text = parseTypeWithoutVariance(signature); if (text == null) throw new ClsFormatException(); for (int i = 0; i < arrayDimensions; i++) text += "[]"; if (variance != '\0') { text = variance + text; } return text; }
@Override public StubElement buildStubTree(FileContent fileContent) { try { VirtualFile file = fileContent.getFile(); Project project = fileContent.getProject(); byte[] content = fileContent.getContent(); final ClsStubBuilderFactory[] factories = Extensions.getExtensions(ClsStubBuilderFactory.EP_NAME); for (ClsStubBuilderFactory factory : factories) { if (!factory.isInnerClass(file) && factory.canBeProcessed(file, content)) { PsiFileStub stub = factory.buildFileStub(file, content, project); if (stub != null) return stub; } } if (!fileContent.getFileName().contains("$")) { LOG.info("No stub built for file " + fileContent); } return null; } catch (ClsFormatException e) { return null; } }
private static void doTest(VirtualFile vFile, String goldFile) throws ClsFormatException, IOException { final PsiFileStub stub = (new DefaultClsStubBuilderFactory()).buildFileStub(vFile, vFile.contentsToByteArray()); assert stub != null : vFile; final String butWas = ((StubBase)stub).printTree(); final String goldFilePath = JavaTestUtil.getJavaTestDataPath() + "/psi/cls/stubBuilder/" + goldFile; String expected = ""; try { expected = FileUtil.loadFile(new File(goldFilePath)); expected = StringUtil.convertLineSeparators(expected); } catch (FileNotFoundException e) { System.out.println("No expected data found at: " + goldFilePath + ", creating one."); final FileWriter fileWriter = new FileWriter(goldFilePath); try { fileWriter.write(butWas); fileWriter.close(); } finally { fileWriter.close(); fail("No test data found. Created one"); } } assertEquals(expected, butWas); }
private void initConstantPool() throws ClsFormatException { if (myConstantPoolOffsets == null){ BytePointer ptr = new BytePointer(getData(), 0); ConstantPoolIterator iterator = new ConstantPoolIterator(ptr); myConstantPoolOffsets = new int[iterator.getEntryCount()]; myConstantPoolOffsets[0] = iterator.getCurrentOffset(); int index = 1; while (iterator.hasMoreEntries()) { int tag = ClsUtil.readU1(ptr); if (tag == ClsUtil.CONSTANT_Long || tag == ClsUtil.CONSTANT_Double) { myConstantPoolOffsets[index++] = ptr.offset + 8; // takes 2 entries! } iterator.next(); myConstantPoolOffsets[index++] = iterator.getCurrentOffset(); } } }
private ConstantValue readConstant(final BytePointer ptr) throws ClsFormatException { final int tag = ClsUtil.readU1(ptr); switch (tag) { case ClsUtil.CONSTANT_Integer : int value = ClsUtil.readU4(ptr); return new IntegerConstantValue(value); case ClsUtil.CONSTANT_Float: float floatValue = ClsUtil.readFloat(ptr); return new FloatConstantValue(floatValue); case ClsUtil.CONSTANT_Long : int high = ClsUtil.readU4(ptr); int low = ClsUtil.readU4(ptr); long v = ((long)high << 32) | (low & 0xFFFFFFFFL); return new LongConstantValue(v); case ClsUtil.CONSTANT_Double : double doubleValue = ClsUtil.readDouble(ptr); return new DoubleConstantValue(doubleValue); case ClsUtil.CONSTANT_String : int stringIndex = ClsUtil.readU2(ptr); ptr.offset = getOffsetInConstantPool(stringIndex); return new StringConstantValue(ClsUtil.readUtf8Info(ptr)); default : throw new ClsFormatException(); } }
public ConstantPoolIterator(BytePointer ptr) throws ClsFormatException { myPtr = ptr; myPtr.offset = 0; int magic = ClsUtil.readU4(myPtr); if (magic != ClsUtil.MAGIC){ throw new ClsFormatException(); } myPtr.offset += 2; // minor version myPtr.offset += 2; // major version myEntryCount = ClsUtil.readU2(myPtr); if (myEntryCount < 1){ throw new ClsFormatException(); } myCurrentEntryIndex = 1; // Entry at index 0 is included in the count but is not present in the constant pool myCurrentOffset = myPtr.offset; }
@NotNull public static List<Pair<String, String[]>> parseTypeParametersDeclaration(CharacterIterator signature, Function<String, String> mapping) throws ClsFormatException { if(signature.current() != '<') { return Collections.emptyList(); } List<Pair<String, String[]>> typeParameters = ContainerUtil.newArrayList(); signature.next(); while(signature.current() != '>') { typeParameters.add(parseTypeParameter(signature, mapping)); } signature.next(); return typeParameters; }
private static String parseTypeVariableRefSignature(CharacterIterator signature) throws ClsFormatException { StringBuilder id = new StringBuilder(); signature.next(); while(signature.current() != ';' && signature.current() != '>' && signature.current() != CharacterIterator.DONE) { id.append(signature.current()); signature.next(); } if(signature.current() == CharacterIterator.DONE) { throw new ClsFormatException(); } if(signature.current() == ';') { signature.next(); } return id.toString(); }
private static String parseClassOrTypeVariableElement(CharacterIterator signature, Function<String, String> mapping) throws ClsFormatException { char variance = parseVariance(signature); if(variance == '*') { return decorateTypeText(null, variance); } int dimensions = parseDimensions(signature); String text = parseTypeWithoutVariance(signature, mapping); if(text == null) { throw new ClsFormatException(); } if(dimensions > 0) { text += StringUtil.repeat("[]", dimensions); } return decorateTypeText(text, variance); }
@NotNull public static String parseTypeString(CharacterIterator signature, Function<String, String> mapping) throws ClsFormatException { int dimensions = parseDimensions(signature); String text = parseTypeWithoutVariance(signature, mapping); if(text == null) { throw new ClsFormatException(); } if(dimensions > 0) { text += StringUtil.repeat("[]", dimensions); } return text; }
private ClassInfo parseClassSignature(String signature) throws ClsFormatException { ClassInfo result = new ClassInfo(); CharacterIterator iterator = new StringCharacterIterator(signature); result.typeParameters = SignatureParsing.parseTypeParametersDeclaration(iterator, myMapping); result.superName = SignatureParsing.parseTopLevelClassRefSignature(iterator, myMapping); while(iterator.current() != CharacterIterator.DONE) { String name = SignatureParsing.parseTopLevelClassRefSignature(iterator, myMapping); if(name == null) { throw new ClsFormatException(); } if(result.interfaceNames == null) { result.interfaceNames = ContainerUtil.newSmartList(); } result.interfaceNames.add(name); } return result; }
private TypeInfo fieldType(String desc, String signature) { String type = null; if(signature != null) { try { type = SignatureParsing.parseTypeString(new StringCharacterIterator(signature), myMapping); } catch(ClsFormatException e) { if(LOG.isDebugEnabled()) { LOG.debug("source=" + mySource + " signature=" + signature, e); } } } if(type == null) { type = toJavaType(Type.getType(desc), myMapping); } return TypeInfo.fromString(type, false); }
private static void doTest(VirtualFile vFile, String goldFile) throws ClsFormatException, IOException { final PsiFileStub stub = ClsFileImpl.buildFileStub(vFile, vFile.contentsToByteArray()); assert stub != null : vFile; final String butWas = ((StubBase)stub).printTree(); final String goldFilePath = JavaTestUtil.getJavaTestDataPath() + "/psi/cls/stubBuilder/" + goldFile; String expected = ""; try { expected = FileUtil.loadFile(new File(goldFilePath)); expected = StringUtil.convertLineSeparators(expected); } catch (FileNotFoundException e) { System.out.println("No expected data found at: " + goldFilePath + ", creating one."); final FileWriter fileWriter = new FileWriter(goldFilePath); try { fileWriter.write(butWas); fileWriter.close(); } finally { fileWriter.close(); fail("No test data found. Created one"); } } assertEquals(expected, butWas); }
public PsiMethodStubImpl(StubElement parent, String name, byte flags, String signature, @NotNull List<String> args, @Nullable List<String> throwables, String desc, int modifiersMask) { super(parent, isAnnotationMethod(flags) ? JavaStubElementTypes.ANNOTATION_METHOD : JavaStubElementTypes.METHOD); myName = name; myDefaultValueText = null; new PsiModifierListStubImpl(this, modifiersMask); String returnType = null; boolean parsedViaGenericSignature = false; if (signature != null) { try { returnType = StubBuildingVisitor.parseMethodViaGenericSignature(signature, this, args, throwables); parsedViaGenericSignature = true; } catch (ClsFormatException ignored) { } } if (returnType == null) { returnType = StubBuildingVisitor.parseMethodViaDescription(desc, this, args); } myReturnType = TypeInfo.fromString(returnType); myFlags = (byte)(flags | (parsedViaGenericSignature ? PARSED_VIA_GENERIC_SIGNATURE : 0)); }
public static PsiTypeParameterListStub parseTypeParametersDeclaration(CharacterIterator iterator, StubElement parentStub) throws ClsFormatException { PsiTypeParameterListStub list = new PsiTypeParameterListStubImpl(parentStub); if (iterator.current() == '<') { iterator.next(); while (iterator.current() != '>') { parseTypeParameter(iterator, list); } iterator.next(); } return list; }
private static PsiTypeParameterStub parseTypeParameter(CharacterIterator iterator, PsiTypeParameterListStub parent) throws ClsFormatException { StringBuilder name = new StringBuilder(); while (iterator.current() != ':' && iterator.current() != CharacterIterator.DONE) { name.append(iterator.current()); iterator.next(); } if (iterator.current() == CharacterIterator.DONE) { throw new ClsFormatException(); } //todo parse annotations on type param PsiTypeParameterStub parameterStub = new PsiTypeParameterStubImpl(parent, StringRef.fromString(name.toString())); // postpone list allocation till a second bound is seen; ignore sole Object bound List<String> bounds = null; boolean jlo = false; while (iterator.current() == ':') { iterator.next(); String bound = parseTopLevelClassRefSignature(iterator); if (bound == null) continue; if (bounds == null) { if (CommonClassNames.JAVA_LANG_OBJECT.equals(bound)) { jlo = true; continue; } bounds = ContainerUtil.newSmartList(); if (jlo) { bounds.add(CommonClassNames.JAVA_LANG_OBJECT); } } bounds.add(bound); } StubBuildingVisitor.newReferenceList(JavaStubElementTypes.EXTENDS_BOUND_LIST, parameterStub, ArrayUtil.toStringArray(bounds)); return parameterStub; }
@Nullable public static String parseTopLevelClassRefSignature(CharacterIterator signature) throws ClsFormatException { if (signature.current() == 'L') { return parseParameterizedClassRefSignature(signature); } if (signature.current() == 'T') { return parseTypeVariableRefSignature(signature); } return null; }
private static void processTypeArgument(CharacterIterator signature, StringBuilder canonicalText) throws ClsFormatException { String typeArgument = parseClassOrTypeVariableElement(signature); canonicalText.append(typeArgument); if (signature.current() != '>') { canonicalText.append(','); } }
@Nullable private static String parseClassSignature(final CharacterIterator signatureIterator, final List<String> convertedInterfaces) throws ClsFormatException { final String convertedSuper = SignatureParsing.parseTopLevelClassRefSignature(signatureIterator); while (signatureIterator.current() != CharacterIterator.DONE) { final String ifs = SignatureParsing.parseTopLevelClassRefSignature(signatureIterator); if (ifs == null) throw new ClsFormatException(); convertedInterfaces.add(ifs); } return convertedSuper; }
@NotNull public static TypeInfo fieldType(String desc, String signature) { if (signature != null) { try { return TypeInfo.fromString(SignatureParsing.parseTypeString(new StringCharacterIterator(signature, 0))); } catch (ClsFormatException e) { return fieldTypeViaDescription(desc); } } else { return fieldTypeViaDescription(desc); } }
@NotNull public static String parseMethodViaGenericSignature(@NotNull String signature, @NotNull PsiMethodStubImpl stub, @NotNull List<String> args, @Nullable List<String> throwables) throws ClsFormatException { StringCharacterIterator iterator = new StringCharacterIterator(signature); SignatureParsing.parseTypeParametersDeclaration(iterator, stub); if (iterator.current() != '(') { throw new ClsFormatException(); } iterator.next(); while (iterator.current() != ')' && iterator.current() != CharacterIterator.DONE) { args.add(SignatureParsing.parseTypeString(iterator)); } if (iterator.current() != ')') { throw new ClsFormatException(); } iterator.next(); String returnType = SignatureParsing.parseTypeString(iterator); while (iterator.current() == '^') { iterator.next(); String exType = SignatureParsing.parseTypeString(iterator); if (throwables != null) { throwables.add(exType); } } return returnType; }
public static PsiTypeParameterListStub parseTypeParametersDeclaration(CharacterIterator signatureIterator, StubElement parentStub) throws ClsFormatException { PsiTypeParameterListStub list = new PsiTypeParameterListStubImpl(parentStub); if (signatureIterator.current() == '<') { signatureIterator.next(); while (signatureIterator.current() != '>') { parseTypeParameter(signatureIterator, list); } signatureIterator.next(); } return list; }
private static PsiTypeParameterStub parseTypeParameter(CharacterIterator signatureIterator, PsiTypeParameterListStub parent) throws ClsFormatException { StringBuilder name = new StringBuilder(); while (signatureIterator.current() != ':' && signatureIterator.current() != CharacterIterator.DONE) { name.append(signatureIterator.current()); signatureIterator.next(); } if (signatureIterator.current() == CharacterIterator.DONE) { throw new ClsFormatException(); } //todo parse annotations on type param PsiTypeParameterStub parameterStub = new PsiTypeParameterStubImpl(parent, StringRef.fromString(name.toString())); ArrayList<String> bounds = null; while (signatureIterator.current() == ':') { signatureIterator.next(); String bound = parseTopLevelClassRefSignature(signatureIterator); if (bound != null && !bound.equals(CommonClassNames.JAVA_LANG_OBJECT)) { if (bounds == null) bounds = new ArrayList<String>(); bounds.add(bound); } } StubBuildingVisitor.newReferenceList(JavaStubElementTypes.EXTENDS_BOUND_LIST, parameterStub, ArrayUtil.toStringArray(bounds)); return parameterStub; }
private static void processTypeArgument(CharacterIterator signature, StringBuffer canonicalText) throws ClsFormatException { String typeArgument = parseClassOrTypeVariableElement(signature); canonicalText.append(typeArgument); if (signature.current() != '>') { canonicalText.append(','); } }
@NotNull private static TypeInfo fieldType(String desc, String signature) { if (signature != null) { try { return TypeInfo.fromString(SignatureParsing.parseTypeString(new StringCharacterIterator(signature, 0))); } catch (ClsFormatException e) { return fieldTypeViaDescription(desc); } } else { return fieldTypeViaDescription(desc); } }
private static String parseMethodViaGenericSignature(final String signature, final PsiMethodStubImpl stub, final List<String> args, final List<String> throwables) throws ClsFormatException { StringCharacterIterator iterator = new StringCharacterIterator(signature); SignatureParsing.parseTypeParametersDeclaration(iterator, stub); if (iterator.current() != '(') { throw new ClsFormatException(); } iterator.next(); while (iterator.current() != ')' && iterator.current() != CharacterIterator.DONE) { args.add(SignatureParsing.parseTypeString(iterator)); } if (iterator.current() != ')') { throw new ClsFormatException(); } iterator.next(); String returnType = SignatureParsing.parseTypeString(iterator); while (iterator.current() == '^') { iterator.next(); throwables.add(SignatureParsing.parseTypeString(iterator)); } return returnType; }
public int importClassInfo(ClassFileReader reader, SymbolTable symbolTable) throws ClsFormatException, CacheCorruptedException { try { final ClassInfo classInfo = new ClassInfo(reader, symbolTable); myQNameToClassInfoMap.put(classInfo.getQualifiedName(), classInfo); return classInfo.getQualifiedName(); } catch (IOException e) { throw new CacheCorruptedException(e); } }
public int reparseClassFile(@NotNull File file, final byte[] fileContent) throws ClsFormatException, CacheCorruptedException { SymbolTable symbolTable = getSymbolTable(); final int qName = getNewClassesCache().importClassInfo(new ClassFileReader(file, symbolTable, fileContent), symbolTable); addClassToUpdate(qName); addTraverseRoot(qName); return qName; }
public ClassInfo(ClassFileReader reader, SymbolTable symbolTable) throws CacheCorruptedException { try { final int qName = symbolTable.getId(reader.getQualifiedName()); myQualifiedName = qName; final String genericSignature = reader.getGenericSignature(); myGenericSignature = genericSignature != null? symbolTable.getId(genericSignature) : -1; myPath = reader.getPath(); final String superClass = reader.getSuperClass(); final int superQName = "".equals(superClass)? -1 : symbolTable.getId(superClass); mySuperQualifiedName = superQName; LOG.assertTrue(superQName != qName); final String[] superInterfaces = reader.getSuperInterfaces(); mySuperInterfaces = ArrayUtil.newIntArray(superInterfaces.length); for (int idx = 0; idx < superInterfaces.length; idx++) { mySuperInterfaces[idx] = symbolTable.getId(superInterfaces[idx]); } final String sourceFileName = reader.getSourceFileName(); mySourceFileName = sourceFileName != null? sourceFileName : ""; myFlags = reader.getAccessFlags(); myRuntimeVisibleAnnotations = reader.getRuntimeVisibleAnnotations(); myRuntimeInvisibleAnnotations = reader.getRuntimeInvisibleAnnotations(); final Collection<ReferenceInfo> refs = reader.getReferences(); myReferences = refs.toArray(new ReferenceInfo[refs.size()]); myFields = reader.getFields(); myMethods = reader.getMethods(); } catch (ClsFormatException e) { throw new CacheCorruptedException(e); } }
private String getSymbol(final int id) throws ClsFormatException { try { return mySymbolTable.getSymbol(id); } catch (CacheCorruptedException e) { throw new ClsFormatException(e.getLocalizedMessage()); } }
private int getSymbolId(final String symbol) throws ClsFormatException{ try { return mySymbolTable.getId(symbol); } catch (CacheCorruptedException e) { throw new ClsFormatException(e.getLocalizedMessage()); } }
public String getQualifiedName() throws ClsFormatException { if (myQualifiedName == null) { BytePointer ptr = new BytePointer(getData(), getConstantPoolEnd() + 2); ptr.offset = getOffsetInConstantPool(ClsUtil.readU2(ptr)); int tag = ClsUtil.readU1(ptr); if (tag != ClsUtil.CONSTANT_Class){ throw new ClsFormatException(); } ptr.offset = getOffsetInConstantPool(ClsUtil.readU2(ptr)); myQualifiedName = ClsUtil.readUtf8Info(ptr, '/', '.'); // keep '$' in the names } return myQualifiedName; }