From 6d808b67cd342272be28f68c22f6ea60f39b1fd5 Mon Sep 17 00:00:00 2001 From: Matthew Aguirre Date: Wed, 16 Sep 2015 20:34:12 -0400 Subject: [PATCH 1/5] Initial build w/ use of ServiceLoader for loading languages. --- .gitignore | 15 +- pom.xml | 91 + .../org/fife/rsta/ac/LanguageSupport.java | 1 - .../fife/rsta/ac/LanguageSupportFactory.java | 378 ++-- .../rsta/ac/LanguageSupportRegistration.java | 17 + .../ac/bsh/AbstractJavaSourceCompletion.java | 81 + .../org/fife/rsta/ac/bsh/ClassCompletion.java | 232 +++ .../org/fife/rsta/ac/bsh/DecoratableIcon.java | 155 ++ .../ac/bsh/DocCommentCompletionProvider.java | 121 ++ .../org/fife/rsta/ac/bsh/FieldCompletion.java | 180 ++ .../java/org/fife/rsta/ac/bsh/FieldData.java | 139 ++ .../org/fife/rsta/ac/bsh/FieldInfoData.java | 212 +++ .../org/fife/rsta/ac/bsh/IconFactory.java | 180 ++ .../java/org/fife/rsta/ac/bsh/JarManager.java | 433 +++++ .../java/org/fife/rsta/ac/bsh/JarReader.java | 162 ++ .../fife/rsta/ac/bsh/JavaCellRenderer.java | 210 +++ .../rsta/ac/bsh/JavaCompletionProvider.java | 193 ++ .../rsta/ac/bsh/JavaLanguageRegistration.java | 27 + .../fife/rsta/ac/bsh/JavaLanguageSupport.java | 594 ++++++ .../fife/rsta/ac/bsh/JavaLinkGenerator.java | 268 +++ .../ac/bsh/JavaParamListCellRenderer.java | 69 + .../java/org/fife/rsta/ac/bsh/JavaParser.java | 164 ++ .../rsta/ac/bsh/JavaShorthandCompletion.java | 110 ++ .../ac/bsh/JavaShorthandCompletionCache.java | 95 + .../rsta/ac/bsh/JavaSourceCompletion.java | 45 + .../rsta/ac/bsh/JavaTemplateCompletion.java | 70 + .../fife/rsta/ac/bsh/JavadocUrlHandler.java | 371 ++++ .../rsta/ac/bsh/LocalVariableCompletion.java | 73 + .../fife/rsta/ac/bsh/MemberCompletion.java | 111 ++ .../fife/rsta/ac/bsh/MethodCompletion.java | 332 ++++ .../java/org/fife/rsta/ac/bsh/MethodData.java | 121 ++ .../org/fife/rsta/ac/bsh/MethodInfoData.java | 371 ++++ .../org/fife/rsta/ac/bsh/PackageMapNode.java | 385 ++++ .../rsta/ac/bsh/PackageNameCompletion.java | 58 + .../rsta/ac/bsh/SourceCompletionProvider.java | 1072 +++++++++++ .../ac/bsh/SourceParamChoicesProvider.java | 337 ++++ src/main/java/org/fife/rsta/ac/bsh/Util.java | 728 ++++++++ .../bsh/buildpath/ClassEnumerationReader.java | 112 ++ .../bsh/buildpath/ClasspathLibraryInfo.java | 220 +++ .../buildpath/ClasspathSourceLocation.java | 70 + .../rsta/ac/bsh/buildpath/DirLibraryInfo.java | 195 ++ .../ac/bsh/buildpath/DirSourceLocation.java | 96 + .../rsta/ac/bsh/buildpath/JarLibraryInfo.java | 214 +++ .../rsta/ac/bsh/buildpath/LibraryInfo.java | 283 +++ .../rsta/ac/bsh/buildpath/SourceLocation.java | 53 + .../ac/bsh/buildpath/ZipSourceLocation.java | 104 ++ .../rsta/ac/bsh/classreader/AccessFlags.java | 109 ++ .../rsta/ac/bsh/classreader/ClassFile.java | 772 ++++++++ .../bsh/classreader/ExceptionTableEntry.java | 126 ++ .../rsta/ac/bsh/classreader/FieldInfo.java | 279 +++ .../fife/rsta/ac/bsh/classreader/Frame.java | 117 ++ .../rsta/ac/bsh/classreader/MemberInfo.java | 188 ++ .../rsta/ac/bsh/classreader/MethodInfo.java | 721 +++++++ .../fife/rsta/ac/bsh/classreader/Util.java | 102 + .../classreader/attributes/AttributeInfo.java | 70 + .../ac/bsh/classreader/attributes/Code.java | 305 +++ .../classreader/attributes/ConstantValue.java | 103 + .../classreader/attributes/Exceptions.java | 88 + .../bsh/classreader/attributes/Signature.java | 424 +++++ .../classreader/attributes/SourceFile.java | 73 + .../attributes/UnsupportedAttribute.java | 65 + .../constantpool/ConstantClassInfo.java | 69 + .../constantpool/ConstantDoubleInfo.java | 73 + .../constantpool/ConstantFieldrefInfo.java | 64 + .../constantpool/ConstantFloatInfo.java | 64 + .../constantpool/ConstantIntegerInfo.java | 62 + .../ConstantInterfaceMethodrefInfo.java | 66 + .../ConstantInvokeDynamicInfo.java | 63 + .../constantpool/ConstantLongInfo.java | 67 + .../ConstantMethodHandleInfo.java | 62 + .../constantpool/ConstantMethodTypeInfo.java | 52 + .../constantpool/ConstantMethodrefInfo.java | 64 + .../constantpool/ConstantNameAndTypeInfo.java | 63 + .../constantpool/ConstantPoolInfo.java | 47 + .../constantpool/ConstantPoolInfoFactory.java | 127 ++ .../constantpool/ConstantStringInfo.java | 69 + .../constantpool/ConstantTypes.java | 50 + .../constantpool/ConstantUtf8Info.java | 135 ++ .../org/fife/rsta/ac/bsh/rjc/ast/ASTNode.java | 53 + .../rsta/ac/bsh/rjc/ast/AbstractASTNode.java | 94 + .../rsta/ac/bsh/rjc/ast/AbstractMember.java | 63 + .../rjc/ast/AbstractTypeDeclarationNode.java | 288 +++ .../fife/rsta/ac/bsh/rjc/ast/CodeBlock.java | 203 ++ .../rsta/ac/bsh/rjc/ast/CompilationUnit.java | 290 +++ .../fife/rsta/ac/bsh/rjc/ast/EnumBody.java | 46 + .../rsta/ac/bsh/rjc/ast/EnumDeclaration.java | 36 + .../org/fife/rsta/ac/bsh/rjc/ast/Field.java | 68 + .../rsta/ac/bsh/rjc/ast/FormalParameter.java | 61 + .../ac/bsh/rjc/ast/ImportDeclaration.java | 48 + .../rsta/ac/bsh/rjc/ast/LocalVariable.java | 47 + .../org/fife/rsta/ac/bsh/rjc/ast/Member.java | 63 + .../org/fife/rsta/ac/bsh/rjc/ast/Method.java | 148 ++ .../bsh/rjc/ast/NormalClassDeclaration.java | 142 ++ .../rjc/ast/NormalInterfaceDeclaration.java | 63 + .../org/fife/rsta/ac/bsh/rjc/ast/Package.java | 24 + .../rsta/ac/bsh/rjc/ast/TypeDeclaration.java | 173 ++ .../bsh/rjc/ast/TypeDeclarationContainer.java | 27 + .../fife/rsta/ac/bsh/rjc/lang/Annotation.java | 30 + .../fife/rsta/ac/bsh/rjc/lang/Modifiers.java | 193 ++ .../org/fife/rsta/ac/bsh/rjc/lang/Type.java | 193 ++ .../rsta/ac/bsh/rjc/lang/TypeArgument.java | 61 + .../rsta/ac/bsh/rjc/lang/TypeParameter.java | 57 + .../fife/rsta/ac/bsh/rjc/lang/Variable.java | 51 + .../fife/rsta/ac/bsh/rjc/lexer/Offset.java | 33 + .../fife/rsta/ac/bsh/rjc/lexer/Scanner.java | 870 +++++++++ .../ac/bsh/rjc/lexer/SourceCodeScanner.flex | 393 ++++ .../ac/bsh/rjc/lexer/SourceCodeScanner.java | 1663 +++++++++++++++++ .../org/fife/rsta/ac/bsh/rjc/lexer/Token.java | 55 + .../fife/rsta/ac/bsh/rjc/lexer/TokenImpl.java | 167 ++ .../rsta/ac/bsh/rjc/lexer/TokenTypes.java | 141 ++ .../rsta/ac/bsh/rjc/notices/ParserNotice.java | 106 ++ .../rsta/ac/bsh/rjc/parser/ASTFactory.java | 888 +++++++++ .../org/fife/rsta/ac/bsh/rjc/parser/Main.java | 141 ++ .../rsta/ac/bsh/tree/AstTreeCellRenderer.java | 44 + .../rsta/ac/bsh/tree/JavaOutlineTree.java | 413 ++++ .../fife/rsta/ac/bsh/tree/JavaTreeNode.java | 121 ++ .../rsta/ac/bsh/tree/LocalVarTreeNode.java | 53 + .../fife/rsta/ac/bsh/tree/MemberTreeNode.java | 195 ++ .../ac/bsh/tree/TypeDeclarationTreeNode.java | 130 ++ .../fife/rsta/ac/c/CLanguageRegistration.java | 27 + .../org/fife/rsta/ac/c/CLanguageSupport.java | 3 +- .../rsta/ac/css/CssLanguageRegistration.java | 27 + .../fife/rsta/ac/css/CssLanguageSupport.java | 1 - .../org/fife/rsta/ac/demo/DemoRootPane.java | 46 +- .../ac/groovy/GroovyLanguageRegistration.java | 27 + .../rsta/ac/groovy/GroovyLanguageSupport.java | 1 - .../ac/html/HtmlLanguageRegistration.java | 27 + .../rsta/ac/html/HtmlLanguageSupport.java | 1 - .../ac/java/JavaLanguageRegistration.java | 27 + .../fife/rsta/ac/java/JavadocUrlHandler.java | 4 +- .../ac/java/SourceParamChoicesProvider.java | 5 +- .../rsta/ac/java/tree/JavaOutlineTree.java | 4 +- .../ac/js/JavaScriptLanguageRegistration.java | 27 + .../rsta/ac/js/JavaScriptLanguageSupport.java | 1 - .../ac/js/tree/JavaScriptOutlineTree.java | 5 +- .../rsta/ac/jsp/JspLanguageRegistration.java | 27 + .../fife/rsta/ac/jsp/JspLanguageSupport.java | 3 +- .../ac/less/LessLanguageRegistration.java | 27 + .../rsta/ac/less/LessLanguageSupport.java | 40 +- .../ac/perl/PerlLanguageRegistration.java | 27 + .../rsta/ac/perl/PerlLanguageSupport.java | 2 - .../rsta/ac/php/PhpLanguageRegistration.java | 27 + .../fife/rsta/ac/php/PhpLanguageSupport.java | 163 +- .../rsta/ac/sh/ShellLanguageRegistration.java | 27 + .../fife/rsta/ac/sh/ShellLanguageSupport.java | 1 + .../rsta/ac/xml/XmlLanguageRegistration.java | 27 + .../fife/rsta/ac/xml/XmlLanguageSupport.java | 1 - .../fife/rsta/ac/xml/tree/XmlOutlineTree.java | 5 +- ...g.fife.rsta.ac.LanguageSupportRegistration | 13 + .../org/fife/rsta/ac/bsh/img/abstract_co.gif | Bin 0 -> 79 bytes .../rsta/ac/bsh/img/class_default_obj.gif | Bin 0 -> 604 bytes .../org/fife/rsta/ac/bsh/img/class_obj.gif | Bin 0 -> 586 bytes .../org/fife/rsta/ac/bsh/img/constr_ovr.gif | Bin 0 -> 81 bytes .../org/fife/rsta/ac/bsh/img/deprecated.gif | Bin 0 -> 78 bytes .../fife/rsta/ac/bsh/img/enum_default_obj.gif | Bin 0 -> 587 bytes .../org/fife/rsta/ac/bsh/img/enum_obj.gif | Bin 0 -> 361 bytes .../fife/rsta/ac/bsh/img/enum_private_obj.gif | Bin 0 -> 590 bytes .../rsta/ac/bsh/img/enum_protected_obj.gif | Bin 0 -> 586 bytes .../org/fife/rsta/ac/bsh/img/error_obj.gif | Bin 0 -> 339 bytes .../rsta/ac/bsh/img/field_default_obj.gif | Bin 0 -> 118 bytes .../rsta/ac/bsh/img/field_private_obj.gif | Bin 0 -> 87 bytes .../rsta/ac/bsh/img/field_protected_obj.gif | Bin 0 -> 119 bytes .../fife/rsta/ac/bsh/img/field_public_obj.gif | Bin 0 -> 124 bytes .../org/fife/rsta/ac/bsh/img/final_co.gif | Bin 0 -> 64 bytes .../org/fife/rsta/ac/bsh/img/html_tag_obj.gif | Bin 0 -> 82 bytes .../org/fife/rsta/ac/bsh/img/imp_obj.gif | Bin 0 -> 114 bytes .../org/fife/rsta/ac/bsh/img/impc_obj.gif | Bin 0 -> 185 bytes .../org/fife/rsta/ac/bsh/img/info_obj.gif | Bin 0 -> 121 bytes .../ac/bsh/img/innerclass_default_obj.gif | Bin 0 -> 604 bytes .../ac/bsh/img/innerclass_private_obj.gif | Bin 0 -> 603 bytes .../ac/bsh/img/innerclass_protected_obj.gif | Bin 0 -> 600 bytes .../rsta/ac/bsh/img/innerclass_public_obj.gif | Bin 0 -> 586 bytes .../ac/bsh/img/innerinterface_default_obj.gif | Bin 0 -> 595 bytes .../ac/bsh/img/innerinterface_private_obj.gif | Bin 0 -> 594 bytes .../bsh/img/innerinterface_protected_obj.gif | Bin 0 -> 592 bytes .../ac/bsh/img/innerinterface_public_obj.gif | Bin 0 -> 574 bytes .../fife/rsta/ac/bsh/img/int_default_obj.gif | Bin 0 -> 595 bytes .../org/fife/rsta/ac/bsh/img/int_obj.gif | Bin 0 -> 574 bytes .../org/fife/rsta/ac/bsh/img/jcu_obj.gif | Bin 0 -> 570 bytes .../org/fife/rsta/ac/bsh/img/jdoc_tag_obj.gif | Bin 0 -> 323 bytes .../rsta/ac/bsh/img/localvariable_obj.gif | Bin 0 -> 152 bytes .../org/fife/rsta/ac/bsh/img/methdef_obj.gif | Bin 0 -> 176 bytes .../org/fife/rsta/ac/bsh/img/methpri_obj.gif | Bin 0 -> 183 bytes .../org/fife/rsta/ac/bsh/img/methpro_obj.gif | Bin 0 -> 181 bytes .../org/fife/rsta/ac/bsh/img/methpub_obj.gif | Bin 0 -> 193 bytes .../org/fife/rsta/ac/bsh/img/package_obj.gif | Bin 0 -> 227 bytes .../org/fife/rsta/ac/bsh/img/static_co.gif | Bin 0 -> 79 bytes .../org/fife/rsta/ac/bsh/img/synch_co.gif | Bin 0 -> 165 bytes .../org/fife/rsta/ac/bsh/img/template_obj.gif | Bin 0 -> 359 bytes .../org/fife/rsta/ac/bsh/img/warning_obj.gif | Bin 0 -> 324 bytes .../org/fife/rsta/ac/bsh/resources.properties | 26 + 191 files changed, 22503 insertions(+), 368 deletions(-) create mode 100644 pom.xml create mode 100644 src/main/java/org/fife/rsta/ac/LanguageSupportRegistration.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/AbstractJavaSourceCompletion.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/ClassCompletion.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/DecoratableIcon.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/DocCommentCompletionProvider.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/FieldCompletion.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/FieldData.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/FieldInfoData.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/IconFactory.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/JarManager.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/JarReader.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/JavaCellRenderer.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/JavaCompletionProvider.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/JavaLanguageRegistration.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/JavaLanguageSupport.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/JavaLinkGenerator.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/JavaParamListCellRenderer.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/JavaParser.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/JavaShorthandCompletion.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/JavaShorthandCompletionCache.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/JavaSourceCompletion.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/JavaTemplateCompletion.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/JavadocUrlHandler.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/LocalVariableCompletion.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/MemberCompletion.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/MethodCompletion.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/MethodData.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/MethodInfoData.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/PackageMapNode.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/PackageNameCompletion.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/SourceCompletionProvider.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/SourceParamChoicesProvider.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/Util.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/buildpath/ClassEnumerationReader.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/buildpath/ClasspathLibraryInfo.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/buildpath/ClasspathSourceLocation.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/buildpath/DirLibraryInfo.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/buildpath/DirSourceLocation.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/buildpath/JarLibraryInfo.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/buildpath/LibraryInfo.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/buildpath/SourceLocation.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/buildpath/ZipSourceLocation.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/AccessFlags.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/ClassFile.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/ExceptionTableEntry.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/FieldInfo.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/Frame.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/MemberInfo.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/MethodInfo.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/Util.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/attributes/AttributeInfo.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/attributes/Code.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/attributes/ConstantValue.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/attributes/Exceptions.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/attributes/Signature.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/attributes/SourceFile.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/attributes/UnsupportedAttribute.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantClassInfo.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantDoubleInfo.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantFieldrefInfo.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantFloatInfo.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantIntegerInfo.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantInterfaceMethodrefInfo.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantInvokeDynamicInfo.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantLongInfo.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantMethodHandleInfo.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantMethodTypeInfo.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantMethodrefInfo.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantNameAndTypeInfo.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantPoolInfo.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantPoolInfoFactory.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantStringInfo.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantTypes.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantUtf8Info.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/ast/ASTNode.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/ast/AbstractASTNode.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/ast/AbstractMember.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/ast/AbstractTypeDeclarationNode.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/ast/CodeBlock.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/ast/CompilationUnit.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/ast/EnumBody.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/ast/EnumDeclaration.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/ast/Field.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/ast/FormalParameter.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/ast/ImportDeclaration.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/ast/LocalVariable.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/ast/Member.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/ast/Method.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/ast/NormalClassDeclaration.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/ast/NormalInterfaceDeclaration.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/ast/Package.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/ast/TypeDeclaration.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/ast/TypeDeclarationContainer.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/lang/Annotation.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/lang/Modifiers.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/lang/Type.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/lang/TypeArgument.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/lang/TypeParameter.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/lang/Variable.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/Offset.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/Scanner.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/SourceCodeScanner.flex create mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/SourceCodeScanner.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/Token.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/TokenImpl.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/TokenTypes.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/notices/ParserNotice.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/parser/ASTFactory.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/parser/Main.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/tree/AstTreeCellRenderer.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/tree/JavaOutlineTree.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/tree/JavaTreeNode.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/tree/LocalVarTreeNode.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/tree/MemberTreeNode.java create mode 100644 src/main/java/org/fife/rsta/ac/bsh/tree/TypeDeclarationTreeNode.java create mode 100644 src/main/java/org/fife/rsta/ac/c/CLanguageRegistration.java create mode 100644 src/main/java/org/fife/rsta/ac/css/CssLanguageRegistration.java create mode 100644 src/main/java/org/fife/rsta/ac/groovy/GroovyLanguageRegistration.java create mode 100644 src/main/java/org/fife/rsta/ac/html/HtmlLanguageRegistration.java create mode 100644 src/main/java/org/fife/rsta/ac/java/JavaLanguageRegistration.java create mode 100644 src/main/java/org/fife/rsta/ac/js/JavaScriptLanguageRegistration.java create mode 100644 src/main/java/org/fife/rsta/ac/jsp/JspLanguageRegistration.java create mode 100644 src/main/java/org/fife/rsta/ac/less/LessLanguageRegistration.java create mode 100644 src/main/java/org/fife/rsta/ac/perl/PerlLanguageRegistration.java create mode 100644 src/main/java/org/fife/rsta/ac/php/PhpLanguageRegistration.java create mode 100644 src/main/java/org/fife/rsta/ac/sh/ShellLanguageRegistration.java create mode 100644 src/main/java/org/fife/rsta/ac/xml/XmlLanguageRegistration.java create mode 100644 src/main/resources/META-INF/services/org.fife.rsta.ac.LanguageSupportRegistration create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/abstract_co.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/class_default_obj.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/class_obj.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/constr_ovr.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/deprecated.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/enum_default_obj.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/enum_obj.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/enum_private_obj.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/enum_protected_obj.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/error_obj.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/field_default_obj.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/field_private_obj.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/field_protected_obj.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/field_public_obj.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/final_co.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/html_tag_obj.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/imp_obj.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/impc_obj.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/info_obj.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/innerclass_default_obj.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/innerclass_private_obj.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/innerclass_protected_obj.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/innerclass_public_obj.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/innerinterface_default_obj.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/innerinterface_private_obj.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/innerinterface_protected_obj.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/innerinterface_public_obj.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/int_default_obj.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/int_obj.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/jcu_obj.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/jdoc_tag_obj.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/localvariable_obj.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/methdef_obj.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/methpri_obj.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/methpro_obj.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/methpub_obj.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/package_obj.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/static_co.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/synch_co.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/template_obj.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/img/warning_obj.gif create mode 100644 src/main/resources/org/fife/rsta/ac/bsh/resources.properties diff --git a/.gitignore b/.gitignore index ed647d4c..4956fd47 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,8 @@ -ant-classes -bin -dist -javadoc -*.java~ -build -.gradle +ant-classes +bin +dist +javadoc +*.java~ +build +.gradle +/target/ \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 00000000..ba846a9d --- /dev/null +++ b/pom.xml @@ -0,0 +1,91 @@ + + + 4.0.0 + com.artistech + languagesupport + 2.5.8 + jar + + + + eu.somatik.serviceloader-maven-plugin + serviceloader-maven-plugin + 1.0.3 + + + org.fife.rsta.ac.LanguageSupportRegistration + + + + + + generate + + + + + + org.apache.maven.plugins + maven-dependency-plugin + 2.10 + + + copy-dependencies + package + + copy-dependencies + + + ${project.build.directory}/lib + false + false + true + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.5.1 + + true + + + + + + src/main/resources + true + + + + + + com.artistech + rsyntaxtextarea + 2.5.8 + + + com.artistech + autocomplete + 2.5.8 + + + org.mozilla + rhino + 1.7.7 + + + junit + junit + 4.11 + test + + + + UTF-8 + 1.6 + 1.6 + + \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/LanguageSupport.java b/src/main/java/org/fife/rsta/ac/LanguageSupport.java index 473236f6..3690e1c1 100644 --- a/src/main/java/org/fife/rsta/ac/LanguageSupport.java +++ b/src/main/java/org/fife/rsta/ac/LanguageSupport.java @@ -38,7 +38,6 @@ public interface LanguageSupport { public static final String PROPERTY_LANGUAGE_PARSER = "org.fife.rsta.ac.LanguageSupport.LanguageParser"; - /** * Returns the delay between when the user types a character and when the * code completion popup should automatically appear (if applicable). diff --git a/src/main/java/org/fife/rsta/ac/LanguageSupportFactory.java b/src/main/java/org/fife/rsta/ac/LanguageSupportFactory.java index c309516a..d3a321d0 100644 --- a/src/main/java/org/fife/rsta/ac/LanguageSupportFactory.java +++ b/src/main/java/org/fife/rsta/ac/LanguageSupportFactory.java @@ -14,224 +14,178 @@ import java.beans.PropertyChangeListener; import java.util.HashMap; import java.util.Map; +import java.util.ServiceLoader; import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; import org.fife.ui.rsyntaxtextarea.SyntaxConstants; - /** - * Provides language support (code completion, etc.) for programming - * languages in RSyntaxTextArea. Different languages may have varying - * levels of "support." + * Provides language support (code completion, etc.) for programming languages + * in RSyntaxTextArea. Different languages may have varying levels of "support." * * @author Robert Futrell * @version 1.0 */ -public class LanguageSupportFactory implements PropertyChangeListener { - - private static final LanguageSupportFactory INSTANCE = - new LanguageSupportFactory(); - - /** - * Maps styles to class-names-for-language-supports; this way we can lazily - * create the LanguageSupports when necessary. - */ - private Map styleToSupportClass; - - /** - * Maps syntax styles to language supports for them. - */ - private Map styleToSupport; - - - /** - * Client property set on RSyntaxTextAreas that points to the current - * language support for that text area. - */ - private static final String LANGUAGE_SUPPORT_PROPERTY = - "org.fife.rsta.ac.LanguageSupport"; - - - /** - * Constructor. - */ - private LanguageSupportFactory() { - createSupportMap(); - } - - - /** - * Adds language support for a language. This is a hook for applications - * using this library to add language support for custom languages. - * - * @param style The language to add support for. This should be one of - * the values defined in {@link SyntaxConstants}. Any previous - * language support for this language is removed. - * @param lsClassName The class name of the LanguageSupport. - */ - public void addLanguageSupport(String style, String lsClassName) { - styleToSupportClass.put(style, lsClassName); - } - - - /** - * Creates the mapping of syntax styles to language supports. - */ - private void createSupportMap() { - - styleToSupport = new HashMap(); - styleToSupportClass = new HashMap(); - - String prefix = "org.fife.rsta.ac."; - - addLanguageSupport(SyntaxConstants.SYNTAX_STYLE_C, - prefix + "c.CLanguageSupport"); - addLanguageSupport(SyntaxConstants.SYNTAX_STYLE_CSS, - prefix + "css.CssLanguageSupport"); - addLanguageSupport(SyntaxConstants.SYNTAX_STYLE_GROOVY, - prefix + "groovy.GroovyLanguageSupport"); - addLanguageSupport(SyntaxConstants.SYNTAX_STYLE_HTML, - prefix + "html.HtmlLanguageSupport"); - addLanguageSupport(SyntaxConstants.SYNTAX_STYLE_JAVA, - prefix + "java.JavaLanguageSupport"); - addLanguageSupport(SyntaxConstants.SYNTAX_STYLE_JAVASCRIPT, - prefix + "js.JavaScriptLanguageSupport"); - addLanguageSupport(SyntaxConstants.SYNTAX_STYLE_JSP, - prefix + "jsp.JspLanguageSupport"); - addLanguageSupport(SyntaxConstants.SYNTAX_STYLE_LESS, - prefix + "less.LessLanguageSupport"); - addLanguageSupport(SyntaxConstants.SYNTAX_STYLE_PERL, - prefix + "perl.PerlLanguageSupport"); - addLanguageSupport(SyntaxConstants.SYNTAX_STYLE_PHP, - prefix + "php.PhpLanguageSupport"); - addLanguageSupport(SyntaxConstants.SYNTAX_STYLE_UNIX_SHELL, - prefix + "sh.ShellLanguageSupport"); - addLanguageSupport(SyntaxConstants.SYNTAX_STYLE_XML, - prefix + "xml.XmlLanguageSupport"); - - } - - - /** - * Returns the singleton instance of this class. - * - * @return The singleton instance. - */ - public static LanguageSupportFactory get() { - return INSTANCE; - } - - - /** - * Returns the language support for a programming language. - * - * @param style The language. This should be one of the constants defined - * in {@link SyntaxConstants}. - * @return The language support, or null if none is registered - * for the language specified. - */ - public LanguageSupport getSupportFor(String style) { - - LanguageSupport support = styleToSupport.get(style); - - if (support==null) { - String supportClazz = styleToSupportClass.get(style); - if (supportClazz!=null) { - try { - Class clazz = Class.forName(supportClazz); - support = (LanguageSupport)clazz.newInstance(); - } catch (RuntimeException re) { // FindBugs - throw re; - } catch (Exception e) { - e.printStackTrace(); - } - styleToSupport.put(style, support); - // Always remove from classes to load, so we don't try again - styleToSupportClass.remove(style); - } - } - - return support; - - } - - - /** - * Installs language support on an RSTA depending on its syntax style. - * - * @param textArea The text area to install language support on. - * @see #uninstallSupport(RSyntaxTextArea) - */ - private void installSupport(RSyntaxTextArea textArea) { - String style = textArea.getSyntaxEditingStyle(); - LanguageSupport support = getSupportFor(style); - if (support!=null) { - support.install(textArea); - } - textArea.putClientProperty(LANGUAGE_SUPPORT_PROPERTY, support); - } - - - /** - * Listens for RSyntaxTextAreas to change what language they're - * highlighting, so language support can be updated appropriately. - * - * @param e The event. - */ - public void propertyChange(PropertyChangeEvent e) { - - RSyntaxTextArea source = (RSyntaxTextArea)e.getSource(); - String name = e.getPropertyName(); - if (RSyntaxTextArea.SYNTAX_STYLE_PROPERTY.equals(name)) { - uninstallSupport(source); - installSupport(source); - } - - } - - - /** - * Registers an RSyntaxTextArea to receive language support. The text area - * will get support for the currently highlighted language, and if it - * changes what language it is highlighting, the support will change as - * appropriate. - * - * @param textArea The text area to register. - */ - public void register(RSyntaxTextArea textArea) { - installSupport(textArea); - textArea.addPropertyChangeListener( - RSyntaxTextArea.SYNTAX_STYLE_PROPERTY, this); - } - - - /** - * Uninstalls the language support on an RSyntaxTextArea, if any. - * - * @param textArea The text area. - * @see #installSupport(RSyntaxTextArea) - */ - private void uninstallSupport(RSyntaxTextArea textArea) { - LanguageSupport support = (LanguageSupport)textArea.getClientProperty( - LANGUAGE_SUPPORT_PROPERTY); - if (support!=null) { - support.uninstall(textArea); - } - } - - - /** - * Un-registers an RSyntaxTextArea. This removes any language support - * on it. - * - * @param textArea The text area. - * @see #register(RSyntaxTextArea) - */ - public void unregister(RSyntaxTextArea textArea) { - uninstallSupport(textArea); - textArea.removePropertyChangeListener( - RSyntaxTextArea.SYNTAX_STYLE_PROPERTY, this); - } - - -} \ No newline at end of file +public final class LanguageSupportFactory implements PropertyChangeListener { + + private static final LanguageSupportFactory INSTANCE + = new LanguageSupportFactory(); + + /** + * Maps styles to class-names-for-language-supports; this way we can lazily + * create the LanguageSupports when necessary. + */ + private final Map styleToSupportClass; + + /** + * Maps syntax styles to language supports for them. + */ + private final Map styleToSupport; + + /** + * Client property set on RSyntaxTextAreas that points to the current + * language support for that text area. + */ + private static final String LANGUAGE_SUPPORT_PROPERTY + = "org.fife.rsta.ac.LanguageSupport"; + + /** + * Constructor. + */ + private LanguageSupportFactory() { + styleToSupport = new HashMap(); + styleToSupportClass = new HashMap(); + ServiceLoader s = ServiceLoader.load(LanguageSupportRegistration.class); + for(LanguageSupportRegistration l : s) { + addLanguageSupport(l.getLanguage(), l.getLanguageSupportType()); + } + } + + /** + * Adds language support for a language. This is a hook for applications + * using this library to add language support for custom languages. + * + * @param style The language to add support for. This should be one of the + * values defined in {@link SyntaxConstants}. Any previous language support + * for this language is removed. + * @param lsClassName The class name of the LanguageSupport. + */ + public void addLanguageSupport(String style, String lsClassName) { + styleToSupportClass.put(style, lsClassName); + } + + /** + * Returns the singleton instance of this class. + * + * @return The singleton instance. + */ + public static LanguageSupportFactory get() { + return INSTANCE; + } + + /** + * Returns the language support for a programming language. + * + * @param style The language. This should be one of the constants defined in + * {@link SyntaxConstants}. + * @return The language support, or null if none is registered + * for the language specified. + */ + public LanguageSupport getSupportFor(String style) { + + LanguageSupport support = styleToSupport.get(style); + + if (support == null) { + String supportClazz = styleToSupportClass.get(style); + if (supportClazz != null) { + try { + Class clazz = Class.forName(supportClazz); + support = (LanguageSupport) clazz.newInstance(); + } catch (RuntimeException re) { // FindBugs + throw re; + } catch (Exception e) { + e.printStackTrace(); + } + styleToSupport.put(style, support); + // Always remove from classes to load, so we don't try again + styleToSupportClass.remove(style); + } + } + + return support; + + } + + /** + * Installs language support on an RSTA depending on its syntax style. + * + * @param textArea The text area to install language support on. + * @see #uninstallSupport(RSyntaxTextArea) + */ + private void installSupport(RSyntaxTextArea textArea) { + String style = textArea.getSyntaxEditingStyle(); + LanguageSupport support = getSupportFor(style); + if (support != null) { + support.install(textArea); + } + textArea.putClientProperty(LANGUAGE_SUPPORT_PROPERTY, support); + } + + /** + * Listens for RSyntaxTextAreas to change what language they're + * highlighting, so language support can be updated appropriately. + * + * @param e The event. + */ + public void propertyChange(PropertyChangeEvent e) { + + RSyntaxTextArea source = (RSyntaxTextArea) e.getSource(); + String name = e.getPropertyName(); + if (RSyntaxTextArea.SYNTAX_STYLE_PROPERTY.equals(name)) { + uninstallSupport(source); + installSupport(source); + } + + } + + /** + * Registers an RSyntaxTextArea to receive language support. The text area + * will get support for the currently highlighted language, and if it + * changes what language it is highlighting, the support will change as + * appropriate. + * + * @param textArea The text area to register. + */ + public void register(RSyntaxTextArea textArea) { + installSupport(textArea); + textArea.addPropertyChangeListener( + RSyntaxTextArea.SYNTAX_STYLE_PROPERTY, this); + } + + /** + * Uninstalls the language support on an RSyntaxTextArea, if any. + * + * @param textArea The text area. + * @see #installSupport(RSyntaxTextArea) + */ + private void uninstallSupport(RSyntaxTextArea textArea) { + LanguageSupport support = (LanguageSupport) textArea.getClientProperty( + LANGUAGE_SUPPORT_PROPERTY); + if (support != null) { + support.uninstall(textArea); + } + } + + /** + * Un-registers an RSyntaxTextArea. This removes any language support on it. + * + * @param textArea The text area. + * @see #register(RSyntaxTextArea) + */ + public void unregister(RSyntaxTextArea textArea) { + uninstallSupport(textArea); + textArea.removePropertyChangeListener( + RSyntaxTextArea.SYNTAX_STYLE_PROPERTY, this); + } + +} diff --git a/src/main/java/org/fife/rsta/ac/LanguageSupportRegistration.java b/src/main/java/org/fife/rsta/ac/LanguageSupportRegistration.java new file mode 100644 index 00000000..b7f55a03 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/LanguageSupportRegistration.java @@ -0,0 +1,17 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.fife.rsta.ac; + +/** + * + * @author matta + */ +public interface LanguageSupportRegistration { + + public String getLanguage(); + + public String getLanguageSupportType(); +} diff --git a/src/main/java/org/fife/rsta/ac/bsh/AbstractJavaSourceCompletion.java b/src/main/java/org/fife/rsta/ac/bsh/AbstractJavaSourceCompletion.java new file mode 100644 index 00000000..f9d380ba --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/AbstractJavaSourceCompletion.java @@ -0,0 +1,81 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh; + +import javax.swing.text.JTextComponent; + +import org.fife.ui.autocomplete.BasicCompletion; +import org.fife.ui.autocomplete.Completion; +import org.fife.ui.autocomplete.CompletionProvider; + + +/** + * Base class for Java source completions. + * + * @author Robert Futrell + * @version 1.0 + */ +public abstract class AbstractJavaSourceCompletion extends BasicCompletion + implements JavaSourceCompletion { + + + public AbstractJavaSourceCompletion(CompletionProvider provider, + String replacementText) { + super(provider, replacementText); + } + + + /** + * Overridden to ensure that two completions don't just have the same + * text value (ignoring case), but that they're of the same "type" of + * Completion as well, so, for example, a completion for the + * "String" class won't clash with a completion for a "string" LocalVar. + * + * @param c2 Another completion instance. + * @return How this completion compares to the other one. + */ + @Override + public int compareTo(Completion c2) { + + int rc = -1; + + if (c2==this) { + rc = 0; + } + + else if (c2!=null) { + rc = toString().compareToIgnoreCase(c2.toString()); + if (rc==0) { // Same text value + String clazz1 = getClass().getName(); + clazz1 = clazz1.substring(clazz1.lastIndexOf('.')); + String clazz2 = c2.getClass().getName(); + clazz2 = clazz2.substring(clazz2.lastIndexOf('.')); + rc = clazz1.compareTo(clazz2); + } + } + + return rc; + + } + + + @Override + public String getAlreadyEntered(JTextComponent comp) { + String temp = getProvider().getAlreadyEnteredText(comp); + int lastDot = temp.lastIndexOf('.'); + if (lastDot>-1) { + temp = temp.substring(lastDot+1); + } + return temp; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/ClassCompletion.java b/src/main/java/org/fife/rsta/ac/bsh/ClassCompletion.java new file mode 100644 index 00000000..22a6d4e8 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/ClassCompletion.java @@ -0,0 +1,232 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh; + +import java.awt.Color; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.util.Iterator; +import javax.swing.Icon; + +import org.fife.rsta.ac.bsh.buildpath.SourceLocation; +import org.fife.rsta.ac.bsh.classreader.AccessFlags; +import org.fife.rsta.ac.bsh.classreader.ClassFile; +import org.fife.rsta.ac.bsh.rjc.ast.CompilationUnit; +import org.fife.rsta.ac.bsh.rjc.ast.TypeDeclaration; +import org.fife.ui.autocomplete.Completion; +import org.fife.ui.autocomplete.CompletionProvider; + + +/** + * Completion for a Java class, interface or enum. + * + * @author Robert Futrell + * @version 1.0 + */ +class ClassCompletion extends AbstractJavaSourceCompletion { + + private ClassFile cf; + + + public ClassCompletion(CompletionProvider provider, ClassFile cf) { + super(provider, cf.getClassName(false)); + this.cf = cf; + } + + + /* + * Fixed error when comparing classes of the same name, which did not allow + * classes with same name but different packages. + * Thanks to Guilherme Joao Frantz and Jonatas Schuler for the patch! + */ + @Override + public int compareTo(Completion c2) { + if (c2 == this) { + return 0; + } + // Check for classes with same name, but in different packages + else if(c2.toString().equalsIgnoreCase(toString())) { + if (c2 instanceof ClassCompletion) { + ClassCompletion cc2 = (ClassCompletion)c2; + return getClassName(true).compareTo(cc2.getClassName(true)); + } + } + return super.compareTo(c2); + } + + + @Override + public boolean equals(Object obj) { + return (obj instanceof ClassCompletion) && + ((ClassCompletion)obj).getReplacementText().equals(getReplacementText()); + } + + + /** + * Returns the name of the class represented by this completion. + * + * @param fullyQualified Whether the returned name should be fully + * qualified. + * @return The class name. + * @see #getPackageName() + */ + public String getClassName(boolean fullyQualified){ + return cf.getClassName(fullyQualified); + } + + + /** + * {@inheritDoc} + */ + @Override + public Icon getIcon() { + + // TODO: Add functionality to ClassFile to make this simpler. + + boolean isInterface = false; + boolean isPublic = false; + //boolean isProtected = false; + //boolean isPrivate = false; + boolean isDefault = false; + + int access = cf.getAccessFlags(); + if ((access&AccessFlags.ACC_INTERFACE)>0) { + isInterface = true; + } + + else if (org.fife.rsta.ac.bsh.classreader.Util.isPublic(access)) { + isPublic = true; + } +// else if (org.fife.rsta.ac.java.classreader.Util.isProtected(access)) { +// isProtected = true; +// } +// else if (org.fife.rsta.ac.java.classreader.Util.isPrivate(access)) { +// isPrivate = true; +// } + else { + isDefault = true; + } + + IconFactory fact = IconFactory.get(); + String key = null; + + if (isInterface) { + if (isDefault) { + key = IconFactory.DEFAULT_INTERFACE_ICON; + } + else { + key = IconFactory.INTERFACE_ICON; + } + } + else { + if (isDefault) { + key = IconFactory.DEFAULT_CLASS_ICON; + } + else if (isPublic) { + key = IconFactory.CLASS_ICON; + } + } + + return fact.getIcon(key, cf.isDeprecated()); + + } + + + /** + * Returns the package this class or interface is in. + * + * @return The package, or null if it is not in a package. + * @see #getClassName(boolean) + */ + public String getPackageName() { + return cf.getPackageName(); + } + + + @Override + public String getSummary() { + + SourceCompletionProvider scp = (SourceCompletionProvider)getProvider(); + SourceLocation loc = scp.getSourceLocForClass(cf.getClassName(true)); + + if (loc!=null) { + + CompilationUnit cu = Util.getCompilationUnitFromDisk(loc, cf); + if (cu!=null) { + Iterator i=cu.getTypeDeclarationIterator(); + for (; i.hasNext(); ) { + TypeDeclaration td = i.next(); + String typeName = td.getName(); + // Avoid inner classes, etc. + if (typeName.equals(cf.getClassName(false))) { + String summary = td.getDocComment(); + // Be cautious - might be no doc comment (or a bug?) + if (summary!=null && summary.startsWith("/**")) { + return Util.docCommentToHtml(summary); + } + } + } + } + + } + + // Default to the fully-qualified class name. + return cf.getClassName(true); + + } + + + @Override + public String getToolTipText() { + return "class " + getReplacementText(); + } + + + @Override + public int hashCode() { + return getReplacementText().hashCode(); + } + + + public void rendererText(Graphics g, int x, int y, boolean selected) { + + String s = cf.getClassName(false); + g.drawString(s, x, y); + FontMetrics fm = g.getFontMetrics(); + int newX = x + fm.stringWidth(s); + if (cf.isDeprecated()) { + int midY = y + fm.getDescent() - fm.getHeight()/2; + g.drawLine(x, midY, newX, midY); + } + x = newX; + + s = " - "; + g.drawString(s, x, y); + x += fm.stringWidth(s); + + String pkgName = cf.getClassName(true); + int lastIndexOf = pkgName.lastIndexOf('.'); + if (lastIndexOf != -1) { // Class may not be in a package + pkgName = pkgName.substring(0, lastIndexOf); + Color origColor = g.getColor(); + if (!selected) { + g.setColor(Color.GRAY); + } + g.drawString(pkgName, x, y); + if (!selected) { + g.setColor(origColor); + } + } + + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/DecoratableIcon.java b/src/main/java/org/fife/rsta/ac/bsh/DecoratableIcon.java new file mode 100644 index 00000000..14070370 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/DecoratableIcon.java @@ -0,0 +1,155 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh; + +import java.awt.Component; +import java.awt.Graphics; +import java.util.ArrayList; +import java.util.List; +import javax.swing.Icon; + + + +/** + * An icon that can have an optional "decorations" icon beside of it. + * + * @author Robert Futrell + * @version 1.0 + */ +public class DecoratableIcon implements Icon { + + /** + * The width of this icon. + */ + private int width; + + /** + * The "main" icon (the icon that is decorated). + */ + private Icon mainIcon; + + /** + * The "decoration" icons. + */ + private List decorations; + + /** + * Whether this icon is for a "deprecated" item. + */ + private boolean deprecated; + + /** + * The width of a decoratable icon (16 + 8 + 8, - 8 for overlap). + */ + private static final int DEFAULT_WIDTH = 24; + + + /** + * Constructor. + * + * @param mainIcon The "main" icon. This cannot be null. + */ + public DecoratableIcon(Icon mainIcon) { + this(DEFAULT_WIDTH, mainIcon); + } + + + /** + * Constructor. + * + * @param width The width for this icon. + * @param mainIcon The "main" icon. This cannot be null. + */ + public DecoratableIcon(int width, Icon mainIcon) { + setMainIcon(mainIcon); + this.width = width; + } + + + /** + * Adds a decoration icon. + * + * @param decoration A new decoration icon. This cannot be + * null. + * @see #setMainIcon(Icon) + */ + public void addDecorationIcon(Icon decoration) { + if (decoration==null) { + throw new IllegalArgumentException("decoration cannot be null"); + } + if (decorations==null) { + decorations = new ArrayList(1); // Usually just 1 + } + decorations.add(decoration); + } + + + /** + * {@inheritDoc} + */ + public int getIconHeight() { + return mainIcon.getIconHeight(); + } + + + /** + * {@inheritDoc} + */ + public int getIconWidth() { + return width; + } + + + /** + * {@inheritDoc} + */ + public void paintIcon(Component c, Graphics g, int x, int y) { + if (deprecated) { + IconFactory.get().getIcon(IconFactory.DEPRECATED_ICON). + paintIcon(c, g, x, y); + } + mainIcon.paintIcon(c, g, x, y); + if (decorations!=null) { + x = x + getIconWidth() - 8; + for (int i=decorations.size()-1; i>=0; i--) { + Icon icon = decorations.get(i); + icon.paintIcon(c, g, x, y); + x -= 8; + } + } + } + + + /** + * Sets whether this icon is for a deprecated item. + * + * @param deprecated Whether this icon is for a deprecated item. + */ + public void setDeprecated(boolean deprecated) { + this.deprecated = deprecated; + } + + + /** + * Sets the main icon. + * + * @param icon The "main" icon. This cannot be null. + * @see #addDecorationIcon(Icon) + */ + public void setMainIcon(Icon icon) { + if (icon==null) { + throw new IllegalArgumentException("icon cannot be null"); + } + this.mainIcon = icon; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/DocCommentCompletionProvider.java b/src/main/java/org/fife/rsta/ac/bsh/DocCommentCompletionProvider.java new file mode 100644 index 00000000..adf8528c --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/DocCommentCompletionProvider.java @@ -0,0 +1,121 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh; + +import java.awt.Graphics; +import javax.swing.Icon; + +import org.fife.ui.autocomplete.BasicCompletion; +import org.fife.ui.autocomplete.CompletionProvider; +import org.fife.ui.autocomplete.DefaultCompletionProvider; + + +/** + * Completion provider for documentation comments. + * + * @author Robert Futrell + * @version 1.0 + */ +class DocCommentCompletionProvider extends DefaultCompletionProvider { + + + public DocCommentCompletionProvider() { + + // Block tags + addCompletion(new JavadocCompletion(this, "@author")); + addCompletion(new JavadocCompletion(this, "@deprecated")); + addCompletion(new JavadocCompletion(this, "@exception")); + addCompletion(new JavadocCompletion(this, "@param")); + addCompletion(new JavadocCompletion(this, "@return")); + addCompletion(new JavadocCompletion(this, "@see")); + addCompletion(new JavadocCompletion(this, "@serial")); + addCompletion(new JavadocCompletion(this, "@serialData")); + addCompletion(new JavadocCompletion(this, "@serialField")); + addCompletion(new JavadocCompletion(this, "@since")); + addCompletion(new JavadocCompletion(this, "@throws")); + addCompletion(new JavadocCompletion(this, "@version")); + + // Proposed block tags + addCompletion(new JavadocCompletion(this, "@category")); + addCompletion(new JavadocCompletion(this, "@example")); + addCompletion(new JavadocCompletion(this, "@tutorial")); + addCompletion(new JavadocCompletion(this, "@index")); + addCompletion(new JavadocCompletion(this, "@exclude")); + addCompletion(new JavadocCompletion(this, "@todo")); + addCompletion(new JavadocCompletion(this, "@internal")); + addCompletion(new JavadocCompletion(this, "@obsolete")); + addCompletion(new JavadocCompletion(this, "@threadsafety")); + + // Inline tags + addCompletion(new JavadocTemplateCompletion(this, "{@code}", "{@code}", "{@code ${}}${cursor}")); + addCompletion(new JavadocTemplateCompletion(this, "{@docRoot}", "{@docRoot}", "{@docRoot ${}}${cursor}")); + addCompletion(new JavadocTemplateCompletion(this, "{@inheritDoc}", "{@inheritDoc}", "{@inheritDoc ${}}${cursor}")); + addCompletion(new JavadocTemplateCompletion(this, "{@link}", "{@link}", "{@link ${}}${cursor}")); + addCompletion(new JavadocTemplateCompletion(this, "{@linkplain}", "{@linkplain}", "{@linkplain ${}}${cursor}")); + addCompletion(new JavadocTemplateCompletion(this, "{@literal}", "{@literal}", "{@literal ${}}${cursor}")); + addCompletion(new JavadocTemplateCompletion(this, "{@value}", "{@value}", "{@value ${}}${cursor}")); + + // Other common stuff + addCompletion(new JavaShorthandCompletion(this, "null", "null", "null")); + addCompletion(new JavaShorthandCompletion(this, "true", "true", "true")); + addCompletion(new JavaShorthandCompletion(this, "false", "false", "false")); + + setAutoActivationRules(false, "{@"); + + } + + + /** + * {@inheritDoc} + */ + @Override + protected boolean isValidChar(char ch) { + return Character.isLetterOrDigit(ch) || ch=='_' || ch=='@' || + ch=='{' || ch=='}'; + } + + + /** + * A Javadoc completion. + */ + private static class JavadocCompletion extends BasicCompletion + implements JavaSourceCompletion { + + public JavadocCompletion(CompletionProvider provider, + String replacementText) { + super(provider, replacementText); + } + + @Override + public Icon getIcon() { + return IconFactory.get().getIcon(IconFactory.JAVADOC_ITEM_ICON); + } + + public void rendererText(Graphics g, int x, int y, boolean selected) { + g.drawString(getReplacementText(), x, y); + } + + } + + + private static class JavadocTemplateCompletion + extends JavaTemplateCompletion { + + public JavadocTemplateCompletion(CompletionProvider provider, + String inputText, String definitionString, String template) { + super(provider, inputText, definitionString, template); + setIcon(IconFactory.JAVADOC_ITEM_ICON); + } + + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/FieldCompletion.java b/src/main/java/org/fife/rsta/ac/bsh/FieldCompletion.java new file mode 100644 index 00000000..42b057e9 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/FieldCompletion.java @@ -0,0 +1,180 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh; + +import java.awt.Graphics; +import javax.swing.Icon; + +import org.fife.rsta.ac.bsh.classreader.FieldInfo; +import org.fife.rsta.ac.bsh.rjc.ast.Field; +import org.fife.rsta.ac.bsh.rjc.lang.Type; +import org.fife.ui.autocomplete.CompletionProvider; + + +/** + * A completion for a Java field. This completion gets its information from + * one of two sources: + * + *
    + *
  • A {@link FieldInfo} instance, which is loaded by parsing a class + * file. This is used when this completion represents a field found + * in a compiled library.
  • + *
  • A {@link Field} instance, which is created when parsing a Java + * source file. This is used when the completion represents a field + * found in uncompiled source, such as the source in an + * RSyntaxTextArea, or in a loose file on disk.
  • + *
+ * + * @author Robert Futrell + * @version 1.0 + */ +class FieldCompletion extends AbstractJavaSourceCompletion + implements MemberCompletion { + + private Data data; + + /** + * The relevance of fields. This allows fields to be "higher" in + * the completion list than other types. + */ + private static final int RELEVANCE = 3; + + + public FieldCompletion(CompletionProvider provider, Field field) { + super(provider, field.getName()); + this.data = new FieldData(field); + setRelevance(RELEVANCE); + } + + + public FieldCompletion(CompletionProvider provider, FieldInfo info) { + super(provider, info.getName()); + this.data = new FieldInfoData(info, (SourceCompletionProvider)provider); + setRelevance(RELEVANCE); + } + + + private FieldCompletion(CompletionProvider provider, String text) { + super(provider, text); + setRelevance(RELEVANCE); + } + + + @Override + public boolean equals(Object obj) { + return (obj instanceof FieldCompletion) && + ((FieldCompletion)obj).getSignature().equals(getSignature()); + } + + + public static FieldCompletion createLengthCompletion( + CompletionProvider provider, final Type type) { + FieldCompletion fc = new FieldCompletion(provider, type.toString()); + fc.data = new Data() { + + public String getEnclosingClassName(boolean fullyQualified) { + return type.getName(fullyQualified); + } + + public String getIcon() { + return IconFactory.FIELD_PUBLIC_ICON; + } + + public String getSignature() { + return "length"; + } + + public String getSummary() { + return null; + } + + public String getType() { + return "int"; + } + + public boolean isConstructor() { + return false; + } + + public boolean isDeprecated() { + return false; + } + + public boolean isAbstract() { + return false; + } + + public boolean isFinal() { + return false; + } + + public boolean isStatic() { + return false; + } + + }; + return fc; + } + + + public String getEnclosingClassName(boolean fullyQualified) { + return data.getEnclosingClassName(fullyQualified); + } + + + @Override + public Icon getIcon() { + return IconFactory.get().getIcon(data); + } + + + public String getSignature() { + return data.getSignature(); + } + + + @Override + public String getSummary() { + + String summary = data.getSummary(); // Could be just the method name + + // If it's the Javadoc for the method... + if (summary!=null && summary.startsWith("/**")) { + summary = org.fife.rsta.ac.bsh.Util.docCommentToHtml(summary); + } + + return summary; + + } + + + public String getType() { + return data.getType(); + } + + + @Override + public int hashCode() { + return getSignature().hashCode(); + } + + + public boolean isDeprecated() { + return data.isDeprecated(); + } + + + public void rendererText(Graphics g, int x, int y, boolean selected) { + MethodCompletion.rendererText(this, g, x, y, selected); + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/FieldData.java b/src/main/java/org/fife/rsta/ac/bsh/FieldData.java new file mode 100644 index 00000000..78161ac2 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/FieldData.java @@ -0,0 +1,139 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh; + +import org.fife.rsta.ac.bsh.MemberCompletion.Data; +import org.fife.rsta.ac.bsh.rjc.ast.Field; +import org.fife.rsta.ac.bsh.rjc.ast.TypeDeclaration; +import org.fife.rsta.ac.bsh.rjc.lang.Modifiers; + + +/** + * Metadata about a field as read from a Java source file. This class is + * used by instances of {@link FieldCompletion}. + * + * @author Robert Futrell + * @version 1.0 + */ +class FieldData implements Data { + + private Field field; + + + public FieldData(Field field) { + this.field = field; + } + + + /** + * {@inheritDoc} + */ + public String getEnclosingClassName(boolean fullyQualified) { + // NOTE: This check isn't really necessary, but is here just in case + // there's a bug in the parsing code. + TypeDeclaration td = field.getParentTypeDeclaration(); + if (td==null) { + new Exception("No parent type declaration for: " + getSignature()). + printStackTrace(); + return ""; + } + return td.getName(fullyQualified); + } + + + /** + * {@inheritDoc} + */ + public String getIcon() { + + String key = null; + + Modifiers mod = field.getModifiers(); + if (mod==null) { + key = IconFactory.FIELD_DEFAULT_ICON; + } + else if (mod.isPrivate()) { + key = IconFactory.FIELD_PRIVATE_ICON; + } + else if (mod.isProtected()) { + key = IconFactory.FIELD_PROTECTED_ICON; + } + else if (mod.isPublic()) { + key = IconFactory.FIELD_PUBLIC_ICON; + } + else { + key = IconFactory.FIELD_DEFAULT_ICON; + } + + return key; + + } + + + /** + * {@inheritDoc} + */ + public String getSignature() { + return field.getName(); + } + + + /** + * {@inheritDoc} + */ + public String getSummary() { + String docComment = field.getDocComment(); + return docComment!=null ? docComment : field.toString(); + } + + + /** + * {@inheritDoc} + */ + public String getType() { + return field.getType().toString(); + } + + + public boolean isAbstract() { + return field.getModifiers().isAbstract(); + } + + + /** + * Always returns false, fields cannot be constructors. + * + * @return false always. + */ + public boolean isConstructor() { + return false; + } + + + /** + * {@inheritDoc} + */ + public boolean isDeprecated() { + return field.isDeprecated(); + } + + + public boolean isFinal() { + return field.getModifiers().isFinal(); + } + + + public boolean isStatic() { + return field.getModifiers().isStatic(); + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/FieldInfoData.java b/src/main/java/org/fife/rsta/ac/bsh/FieldInfoData.java new file mode 100644 index 00000000..6accc76f --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/FieldInfoData.java @@ -0,0 +1,212 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh; + +import java.util.Iterator; + +import org.fife.rsta.ac.bsh.MemberCompletion.Data; +import org.fife.rsta.ac.bsh.buildpath.SourceLocation; +import org.fife.rsta.ac.bsh.classreader.ClassFile; +import org.fife.rsta.ac.bsh.classreader.FieldInfo; +import org.fife.rsta.ac.bsh.classreader.Util; +import org.fife.rsta.ac.bsh.rjc.ast.CompilationUnit; +import org.fife.rsta.ac.bsh.rjc.ast.Field; +import org.fife.rsta.ac.bsh.rjc.ast.Member; +import org.fife.rsta.ac.bsh.rjc.ast.TypeDeclaration; + + +/** + * Metadata about a field as read from a class file. This class is used by + * instances of {@link FieldCompletion}. + * + * @author Robert Futrell + * @version 1.0 + */ +class FieldInfoData implements Data { + + private FieldInfo info; + private SourceCompletionProvider provider; + + + public FieldInfoData(FieldInfo info, SourceCompletionProvider provider) { + this.info = info; + this.provider = provider; + } + + + /** + * {@inheritDoc} + */ + public String getEnclosingClassName(boolean fullyQualified) { + return info.getClassFile().getClassName(fullyQualified); + } + + + /** + * {@inheritDoc} + */ + public String getIcon() { + + String key = null; + int flags = info.getAccessFlags(); + + if (Util.isDefault(flags)) { + key = IconFactory.FIELD_DEFAULT_ICON; + } + else if (Util.isPrivate(flags)) { + key = IconFactory.FIELD_PRIVATE_ICON; + } + else if (Util.isProtected(flags)) { + key = IconFactory.FIELD_PROTECTED_ICON; + } + else if (Util.isPublic(flags)) { + key = IconFactory.FIELD_PUBLIC_ICON; + } + else { + key = IconFactory.FIELD_DEFAULT_ICON; + } + + return key; + + } + + + /** + * {@inheritDoc} + */ + public String getSignature() { + return info.getName(); + } + + + /** + * {@inheritDoc} + */ + public String getSummary() { + + ClassFile cf = info.getClassFile();; + SourceLocation loc = provider.getSourceLocForClass(cf.getClassName(true)); + String summary = null; + + // First, try to parse the Javadoc for this method from the attached + // source. + if (loc!=null) { + summary = getSummaryFromSourceLoc(loc, cf); + } + + // Default to the field name. + if (summary==null) { + summary = info.getName(); + } + return summary; + + } + + + /** + * Scours the source in a location (zip file, directory), looking for a + * particular class's source. If it is found, it is parsed, and the + * Javadoc for this field (if any) is returned. + * + * @param loc The zip file, jar file, or directory to look in. + * @param cf The {@link ClassFile} representing the class of this field. + * @return The summary, or null if the field has no javadoc, + * the class's source was not found, or an IO error occurred. + */ + private String getSummaryFromSourceLoc(SourceLocation loc, ClassFile cf) { + + String summary = null; + CompilationUnit cu = org.fife.rsta.ac.bsh.Util. + getCompilationUnitFromDisk(loc, cf); + + // If the class's source was found and successfully parsed, look for + // this method. + if (cu!=null) { + + Iterator i = cu.getTypeDeclarationIterator(); + while (i.hasNext()) { + + TypeDeclaration td = i.next(); + String typeName = td.getName(); + + // Avoid inner classes, etc. + if (typeName.equals(cf.getClassName(false))) { + + // Locate our field! + Iterator j = td.getMemberIterator(); + while (j.hasNext()) { + Member member = j.next(); + if (member instanceof Field && + member.getName().equals(info.getName())) { + Field f2 = (Field)member; + summary = f2.getDocComment(); + break; + } + } + + } // if (typeName.equals(cf.getClassName(false))) + + } // for (Iterator i=cu.getTypeDeclarationIterator(); i.hasNext(); ) + + } // if (cu!=null) + + return summary; + + } + + + /** + * {@inheritDoc} + */ + public String getType() { + return info.getTypeString(false); + } + + + /** + * Always returns false since fields cannot be abstract. + * + * @return false always. + */ + public boolean isAbstract() { + return false; // Fields cannot be abstract + } + + + /** + * Always returns false, fields cannot be constructors. + * + * @return false always. + */ + public boolean isConstructor() { + return false; + } + + + /** + * {@inheritDoc} + */ + public boolean isDeprecated() { + return info.isDeprecated(); + } + + + public boolean isFinal() { + return info.isFinal(); + } + + + public boolean isStatic() { + return info.isStatic(); + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/IconFactory.java b/src/main/java/org/fife/rsta/ac/bsh/IconFactory.java new file mode 100644 index 00000000..4560c02b --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/IconFactory.java @@ -0,0 +1,180 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh; + +import java.net.URL; +import java.util.HashMap; +import java.util.Map; +import javax.swing.Icon; +import javax.swing.ImageIcon; + + + +/** + * Holds icons used by Java auto-completion. + * + * @author Robert Futrell + * @version 1.0 + */ +public class IconFactory { + + public static final String SOURCE_FILE_ICON = "sourceFileIcon"; + public static final String PACKAGE_ICON = "packageIcon"; + public static final String IMPORT_ROOT_ICON = "importRootIcon"; + public static final String IMPORT_ICON = "importIcon"; + public static final String DEFAULT_CLASS_ICON = "defaultClassIcon"; + public static final String DEFAULT_INTERFACE_ICON = "defaultInterfaceIcon"; + public static final String CLASS_ICON = "classIcon"; + public static final String ENUM_ICON = "enumIcon"; + public static final String ENUM_PROTECTED_ICON = "enumProtectedIcon"; + public static final String ENUM_PRIVATE_ICON = "enumPrivateIcon"; + public static final String ENUM_DEFAULT_ICON = "enumDefaultIcon"; + public static final String INNER_CLASS_PUBLIC_ICON = "innerClassPublicIcon"; + public static final String INNER_CLASS_PROTECTED_ICON = "innerClassProtectedIcon"; + public static final String INNER_CLASS_PRIVATE_ICON = "innerClassPrivateIcon"; + public static final String INNER_CLASS_DEFAULT_ICON = "innerClassDefaultIcon"; + public static final String INTERFACE_ICON = "interfaceIcon"; + public static final String JAVADOC_ITEM_ICON = "javadocItemIcon"; + public static final String LOCAL_VARIABLE_ICON = "localVariableIcon"; + public static final String METHOD_PUBLIC_ICON = "methodPublicIcon"; + public static final String METHOD_PROTECTED_ICON = "methodProtectedIcon"; + public static final String METHOD_PRIVATE_ICON = "methodPrivateIcon"; + public static final String METHOD_DEFAULT_ICON = "methodDefaultIcon"; + public static final String TEMPLATE_ICON = "templateIcon"; + public static final String FIELD_PUBLIC_ICON = "fieldPublicIcon"; + public static final String FIELD_PROTECTED_ICON = "fieldProtectedIcon"; + public static final String FIELD_PRIVATE_ICON = "fieldPrivateIcon"; + public static final String FIELD_DEFAULT_ICON = "fieldDefaultIcon"; + + public static final String CONSTRUCTOR_ICON = "constructorIcon"; + public static final String DEPRECATED_ICON = "deprecatedIcon"; + public static final String ABSTRACT_ICON = "abstractIcon"; + public static final String FINAL_ICON = "finalIcon"; + public static final String STATIC_ICON = "staticIcon"; + + private Map iconMap; + + private static final IconFactory INSTANCE = new IconFactory(); + + + private IconFactory() { + + iconMap = new HashMap(); + iconMap.put(SOURCE_FILE_ICON, loadIcon("jcu_obj.gif")); + iconMap.put(PACKAGE_ICON, loadIcon("package_obj.gif")); + iconMap.put(IMPORT_ROOT_ICON, loadIcon("impc_obj.gif")); + iconMap.put(IMPORT_ICON, loadIcon("imp_obj.gif")); + iconMap.put(DEFAULT_CLASS_ICON, loadIcon("class_default_obj.gif")); + iconMap.put(DEFAULT_INTERFACE_ICON, loadIcon("int_default_obj.gif")); + iconMap.put(CLASS_ICON, loadIcon("class_obj.gif")); + iconMap.put(ENUM_ICON, loadIcon("enum_obj.gif")); + iconMap.put(ENUM_PROTECTED_ICON, loadIcon("enum_protected_obj.gif")); + iconMap.put(ENUM_PRIVATE_ICON, loadIcon("enum_private_obj.gif")); + iconMap.put(ENUM_DEFAULT_ICON, loadIcon("enum_default_obj.gif")); + iconMap.put(INNER_CLASS_PUBLIC_ICON, loadIcon("innerclass_public_obj.gif")); + iconMap.put(INNER_CLASS_PROTECTED_ICON, loadIcon("innerclass_protected_obj.gif")); + iconMap.put(INNER_CLASS_PRIVATE_ICON, loadIcon("innerclass_private_obj.gif")); + iconMap.put(INNER_CLASS_DEFAULT_ICON, loadIcon("innerclass_default_obj.gif")); + iconMap.put(INTERFACE_ICON, loadIcon("int_obj.gif")); + iconMap.put(JAVADOC_ITEM_ICON, loadIcon("jdoc_tag_obj.gif")); + iconMap.put(LOCAL_VARIABLE_ICON, loadIcon("localvariable_obj.gif")); + iconMap.put(METHOD_PUBLIC_ICON, loadIcon("methpub_obj.gif")); + iconMap.put(METHOD_PROTECTED_ICON, loadIcon("methpro_obj.gif")); + iconMap.put(METHOD_PRIVATE_ICON, loadIcon("methpri_obj.gif")); + iconMap.put(METHOD_DEFAULT_ICON, loadIcon("methdef_obj.gif")); + iconMap.put(TEMPLATE_ICON, loadIcon("template_obj.gif")); + iconMap.put(FIELD_PUBLIC_ICON, loadIcon("field_public_obj.gif")); + iconMap.put(FIELD_PROTECTED_ICON, loadIcon("field_protected_obj.gif")); + iconMap.put(FIELD_PRIVATE_ICON, loadIcon("field_private_obj.gif")); + iconMap.put(FIELD_DEFAULT_ICON, loadIcon("field_default_obj.gif")); + + iconMap.put(CONSTRUCTOR_ICON, loadIcon("constr_ovr.gif")); + iconMap.put(DEPRECATED_ICON, loadIcon("deprecated.gif")); + iconMap.put(ABSTRACT_ICON, loadIcon("abstract_co.gif")); + iconMap.put(FINAL_ICON, loadIcon("final_co.gif")); + iconMap.put(STATIC_ICON, loadIcon("static_co.gif")); + + } + + + public static IconFactory get() { + return INSTANCE; + } + + + public Icon getIcon(String key) { + return getIcon(key, false); + } + + + public Icon getIcon(String key, boolean deprecated) { + Icon icon = iconMap.get(key); + if (deprecated) { // TODO: Optimize me + DecoratableIcon di = new DecoratableIcon(16, icon); + di.setDeprecated(deprecated); + icon = di; + } + return icon; + } + + + public Icon getIcon(IconData data) { + // TODO: Optimize me + DecoratableIcon icon = new DecoratableIcon(16, getIcon(data.getIcon())); + icon.setDeprecated(data.isDeprecated()); + if (data.isAbstract()) { + icon.addDecorationIcon(getIcon(ABSTRACT_ICON)); + } + if (data.isStatic()) { + icon.addDecorationIcon(getIcon(STATIC_ICON)); + } + if (data.isFinal()) { + icon.addDecorationIcon(getIcon(FINAL_ICON)); + } + return icon; + } + + + private Icon loadIcon(String name) { + URL res = getClass().getResource("img/" + name); + if (res==null) { + // IllegalArgumentException is what would be thrown if res + // was null anyway, we're just giving the actual arg name to + // make the message more descriptive + throw new IllegalArgumentException("icon not found: img/" + name); + } + return new ImageIcon(res); + } + + + public static interface IconData { + + /** + * Returns the main icon to use when rendering this member's completion. + * This icon will be decorated appropriately based on whether it is + * abstract, deprecated, final, static, or any of the above. + * + * @return The icon to use. + */ + public String getIcon(); + + public boolean isAbstract(); + + public boolean isDeprecated(); + + public boolean isFinal(); + + public boolean isStatic(); + + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/JarManager.java b/src/main/java/org/fife/rsta/ac/bsh/JarManager.java new file mode 100644 index 00000000..532e1563 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/JarManager.java @@ -0,0 +1,433 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.fife.rsta.ac.bsh.buildpath.JarLibraryInfo; +import org.fife.rsta.ac.bsh.buildpath.LibraryInfo; +import org.fife.rsta.ac.bsh.buildpath.SourceLocation; +import org.fife.rsta.ac.bsh.classreader.ClassFile; +import org.fife.rsta.ac.bsh.rjc.ast.ImportDeclaration; +import org.fife.ui.autocomplete.Completion; +import org.fife.ui.autocomplete.CompletionProvider; + + +/** + * Manages a list of jars and gets completions from them. This can be shared + * amongst multiple {@link JavaCompletionProvider} instances. + * + * @author Robert Futrell + * @version 1.0 + */ +public class JarManager { + + /** + * Locations of class files to get completions from. + */ + private List classFileSources; + + /** + * Whether to check datestamps on jars/directories when completion + * information is requested. + */ + private static boolean checkModified; + + + /** + * Constructor. + */ + public JarManager() { + classFileSources = new ArrayList(); + setCheckModifiedDatestamps(true); + } + + + /** + * Adds completions matching the specified text to a list. + * + * @param p The parent completion provider. + * @param text The text to match. + * @param addTo The list to add completion choices to. + */ + public void addCompletions(CompletionProvider p, String text, + Set addTo) { +/* + * The commented-out code below is probably replaced by the rest of the code + * in this method... +TODO: Verify me!!! + * + // Add any completions matching the text for each jar we know about + String[] pkgNames = Util.splitOnChar(text, '.'); + for (int i=0; i-1) { + String[] pkgNames = Util.splitOnChar(text, '.'); + for (int i=0; i classFiles = jar. + getClassesWithNamesStartingWith(lowerCaseText); + if (classFiles!=null) { + for (ClassFile cf : classFiles) { + if (org.fife.rsta.ac.bsh.classreader.Util.isPublic(cf.getAccessFlags())) { + addTo.add(new ClassCompletion(p, cf)); + } + } + } + } + } + + } + + + /** + * Adds a jar to read from. This is a convenience method for folks only + * reading classes from jar files. + * + * @param jarFile The jar to add. This cannot be null. + * @return Whether this jar was added (e.g. it wasn't already loaded, or + * it has a new source path). + * @throws IOException If an IO error occurs. + * @see #addClassFileSource(LibraryInfo) + * @see #addCurrentJreClassFileSource() + * @see #getClassFileSources() + * @see #removeClassFileSource(File) + */ + public boolean addClassFileSource(File jarFile) throws IOException { + if (jarFile==null) { + throw new IllegalArgumentException("jarFile cannot be null"); + } + return addClassFileSource(new JarLibraryInfo(jarFile)); + } + + + /** + * Adds a class file source to read from. + * + * @param info The source to add. If this is null, then + * the current JVM's main JRE jar (rt.jar, or classes.jar on OS X) + * will be added. If this source has already been added, adding it + * again will do nothing (except possibly update its attached source + * location). + * @return Whether this source was added (e.g. it wasn't already loaded, or + * it has a new source path). + * @throws IOException If an IO error occurs. + * @see #addClassFileSource(File) + * @see #addCurrentJreClassFileSource() + * @see #getClassFileSources() + * @see #removeClassFileSource(LibraryInfo) + */ + public boolean addClassFileSource(LibraryInfo info) throws IOException { + + if (info==null) { + throw new IllegalArgumentException("info cannot be null"); + } + + // First see if this jar is already on the "build path." + for (int i=0; inull if there are none. + */ + public List getClassesWithUnqualifiedName(String name, + List importDeclarations) { + + // Might be more than one class/interface/enum with the same name. + List result = null; + + // Loop through all of our imports. + for (ImportDeclaration idec : importDeclarations) { + + // Static imports are for fields/methods, not classes + if (!idec.isStatic()) { + + // Wildcard => See if package contains a class with this name + if (idec.isWildcard()) { + + String qualified = idec.getName(); + qualified = qualified.substring(0, qualified.indexOf('*')); + qualified += name; + ClassFile entry = getClassEntry(qualified); + if (entry!=null) { + if (result==null) { + result = new ArrayList(1); // Usually small + } + result.add(entry); + } + + } + + // Not wildcard => fully-qualified class/interface name + else { + String name2 = idec.getName(); + String unqualifiedName2 = name2.substring(name2.lastIndexOf('.')+1); + if (unqualifiedName2.equals(name)) { + ClassFile entry = getClassEntry(name2); + if (entry!=null) { // Should always be true + if (result==null) { + result = new ArrayList(1); // Usually small + } + result.add(entry); + } + else { + System.err.println("ERROR: Class not found! - " + name2); + } + } + } + + } + + } + + // Also check java.lang + String qualified = "java.lang." + name; + ClassFile entry = getClassEntry(qualified); + if (entry!=null) { + if (result==null) { + result = new ArrayList(1); // Usually small + } + result.add(entry); + } + + return result; + + } + + + /** + * + * @param pkgName A package name. + * @return A list of all classes in that package. + */ + public List getClassesInPackage(String pkgName, boolean inPkg) { + + List list = new ArrayList(); + String[] pkgs = Util.splitOnChar(pkgName, '.'); + + for (int i=0; iLibraryInfo in this list will have no effect on + * this completion provider; in order to do that, you must re-add + * the jar via {@link #addClassFileSource(LibraryInfo)}. If there + * are no jars on the "build path," this will be an empty list. + * @see #addClassFileSource(LibraryInfo) + */ + public List getClassFileSources() { + List jarList = + new ArrayList(classFileSources.size()); + for (JarReader reader : classFileSources) { + jarList.add(reader.getLibraryInfo()); // Already cloned + } + return jarList; + } + + +public SourceLocation getSourceLocForClass(String className) { + SourceLocation sourceLoc = null; + for (int i=0; ifalse + * if the jar was not on the build path. + * @see #removeClassFileSource(LibraryInfo) + * @see #addClassFileSource(LibraryInfo) + * @see #getClassFileSources() + */ + public boolean removeClassFileSource(File jar) { + return removeClassFileSource(new JarLibraryInfo(jar)); + } + + + /** + * Removes a class file source from the "build path." + * + * @param toRemove The source to remove. + * @return Whether source jar was removed. This will be false + * if the source was not on the build path. + * @see #removeClassFileSource(File) + * @see #addClassFileSource(LibraryInfo) + * @see #getClassFileSources() + */ + public boolean removeClassFileSource(LibraryInfo toRemove) { + for (Iterator i=classFileSources.iterator(); i.hasNext(); ) { + JarReader reader = i.next(); + LibraryInfo info = reader.getLibraryInfo(); + if (info.equals(toRemove)) { + i.remove(); + return true; + } + } + return false; + } + + + /** + * Sets whether the "last modified" time stamp on jars and class + * directories should be checked whenever completions are requested, and + * if the jar/directory has been modified since the last time, reload any + * cached class file data. This allows for code completion to update + * whenever dependencies are rebuilt, but has the side effect of increased + * file I/O. By default this option is enabled; if you somehow find the + * file I/O to be a bottleneck (perhaps accessing jars over a slow NFS + * mount), you can disable this option. + * + * @param check Whether to check if any jars/directories have been + * modified since the last access, and clear any cached completion + * information if so. + * @see #getCheckModifiedDatestamps() + */ + public static void setCheckModifiedDatestamps(boolean check) { + checkModified = check; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/JarReader.java b/src/main/java/org/fife/rsta/ac/bsh/JarReader.java new file mode 100644 index 00000000..679aa9ad --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/JarReader.java @@ -0,0 +1,162 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import org.fife.rsta.ac.bsh.buildpath.LibraryInfo; +import org.fife.rsta.ac.bsh.classreader.ClassFile; +import org.fife.ui.autocomplete.Completion; +import org.fife.ui.autocomplete.CompletionProvider; + + +/** + * Reads entries from a source of class files, such as a jar or a "bin/" + * directory. This class acts as an intermediary between a raw + * LibraryInfo and the higher level Java completion classes. + * It caches information about classes and refreshes that cache when + * appropriate. + * + * @author Robert Futrell + * @version 1.0 + */ +class JarReader { + + /** + * Information about the jar or directory we're reading classes from. + */ + private LibraryInfo info; + + /** + * Data structure that caches {@link ClassFile}s. + */ + private PackageMapNode packageMap; + + private long lastModified; + + + /** + * Constructor. + * + * @param info The jar file to read from. This cannot be null. + * @throws IOException If an IO error occurs reading from the jar file. + */ + public JarReader(LibraryInfo info) throws IOException { + this.info = info; + packageMap = new PackageMapNode(); + loadCompletions(); + } + + + /** + * Gets the completions in this jar that match a given string. + * + * @param provider The parent completion provider. + * @param pkgNames The text to match, split into tokens around the + * '.' character. This should be (the start of) a + * fully-qualified class, interface, or enum name. + * @param addTo The list to add completion choices to. + */ + public void addCompletions(CompletionProvider provider, String[] pkgNames, + Set addTo) { + checkLastModified(); + packageMap.addCompletions(info, provider, pkgNames, addTo); + } + + + /** + * Checks whether the jar or class file directory has been modified since + * the last use of this reader. If it has, then any cached + * ClassFiles are cleared, in case any classes have been + * updated. + */ + private void checkLastModified() { + long newLastModified = info.getLastModified(); + if (newLastModified!=0 && newLastModified!=lastModified) { + int count = 0; + count = packageMap.clearClassFiles(); + System.out.println("DEBUG: Cleared " + count + " cached ClassFiles"); + lastModified = newLastModified; + } + } + + + public boolean containsClass(String className) { + return packageMap.containsClass(className); + } + + + public boolean containsPackage(String pkgName) { + return packageMap.containsPackage(pkgName); + } + + + public ClassFile getClassEntry(String[] items) { + return packageMap.getClassEntry(info, items); + } + + + public void getClassesInPackage(List addTo, String[] pkgs, + boolean inPkg) { + packageMap.getClassesInPackage(info, addTo, pkgs, inPkg); + } + + + /** + * Looks through all classes in this jar or directory, trying to find any + * whose unqualified names start with a given prefix. + * + * @param prefix The prefix of the class names. Case is ignored on this + * parameter. + * @return A list of {@link ClassFile}s representing classes in this + * jar or directory whose unqualified names start with the prefix. + * This will never be null, but may of course be + * empty. + */ + public List getClassesWithNamesStartingWith(String prefix) { + List res = new ArrayList(); + String currentPkg = ""; // Don't use null; we're appending to it + packageMap.getClassesWithNamesStartingWith(info, prefix, currentPkg, + res); + return res; + } + + + /** + * Returns the physical file on disk.

+ * + * Modifying the returned object will not have any effect on + * code completion; e.g. changing the source location will not have any + * effect. + * + * @return The info. + */ + public LibraryInfo getLibraryInfo() { + return (LibraryInfo)info.clone(); + } + + + private void loadCompletions() throws IOException { + packageMap = info.createPackageMap(); + lastModified = info.getLastModified(); + } + + + @Override + public String toString() { + return "[JarReader: " + getLibraryInfo() + "]"; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/JavaCellRenderer.java b/src/main/java/org/fife/rsta/ac/bsh/JavaCellRenderer.java new file mode 100644 index 00000000..58ffc5cf --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/JavaCellRenderer.java @@ -0,0 +1,210 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.util.Map; +import javax.swing.DefaultListCellRenderer; +import javax.swing.JList; + +import org.fife.ui.autocomplete.Completion; +import org.fife.ui.rsyntaxtextarea.RSyntaxUtilities; + + +/** + * Cell renderer for Java auto-completion. This renderer attempts to be + * fast due to the possibility of many (100+) auto-completions dynamically + * generated for large Java classes. Using Swing's HTML support is simply + * too slow (see {@link CompletionCellRenderer}).

+ * + * The color scheme for this renderer mimics that found in Eclipse. + * + * @author Robert Futrell + * @version 1.0 + */ +public class JavaCellRenderer extends DefaultListCellRenderer { + + private JList list; + private boolean selected; + private boolean evenRow; + private JavaSourceCompletion jsc; + + /** + * The alternating background color, or null for none. + */ + private static Color altBG; + + /** + * This is used instead of jsc for "incomplete" stuff, like classes, + * interfaces, etc. read from jars (don't yet read the class in, for + * example). + */ + private Completion nonJavaCompletion; + + /** + * Whether to not display extra info (type, etc.)in completion text, just + * the completion's name. The default is false. + */ + private boolean simpleText; + + + /** + * Returns the background color to use on alternating lines. + * + * @return The alternate background color. If this is null, + * alternating colors are not used. + * @see #setAlternateBackground(Color) + */ + public static Color getAlternateBackground() { + return altBG; + } + + + /** + * Returns the renderer. + * + * @param list The list of choices being rendered. + * @param value The {@link Completion} being rendered. + * @param index The index into list being rendered. + * @param selected Whether the item is selected. + * @param hasFocus Whether the item has focus. + */ + @Override + public Component getListCellRendererComponent(JList list, Object value, + int index, boolean selected, boolean hasFocus) { + + super.getListCellRendererComponent(list, value, index, selected, hasFocus); + + setText("Foobar"); // Just something to give it proper height + this.list = list; + this.selected = selected; + + if (value instanceof JavaSourceCompletion) { + jsc = (JavaSourceCompletion)value; + nonJavaCompletion = null; + setIcon(jsc.getIcon()); + } + else { + jsc = null; + nonJavaCompletion = (Completion)value; + setIcon(nonJavaCompletion.getIcon()); + } + + evenRow = (index&1) == 0; + if (altBG!=null && evenRow && !selected) { + setBackground(altBG); + } + + return this; + + } + + + @Override + protected void paintComponent(Graphics g) { + + // Set up rendering hints to look as close to native as possible + Graphics2D g2d = (Graphics2D)g; + Object old = null; + + // First, try to use the rendering hint set that is "native". + Map hints = RSyntaxUtilities.getDesktopAntiAliasHints(); + if (hints!=null) { + old = g2d.getRenderingHints(); + g2d.addRenderingHints(hints); + } + // If a "native" set isn't found, just turn on standard text AA. + else { + old = g2d.getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING); + g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, + RenderingHints.VALUE_TEXT_ANTIALIAS_ON); + } + +// if (jsc!=null) { +// setText(null); // Stop "Foobar" from being painted +// } + + // We never paint "selection" around the icon, to imitate Eclipse + final int iconW = 18; + int h = getHeight(); + if (!selected) { + g.setColor(getBackground()); + g.fillRect(0,0, getWidth(),h); + } + else { + g.setColor(altBG!=null && evenRow ? altBG : list.getBackground()); + g.fillRect(0,0, iconW,h); + g.setColor(getBackground()); // Selection color + g.fillRect(iconW, 0, getWidth()-iconW, h); + } + if (getIcon()!=null) { + int y = (h - getIcon().getIconHeight())/2; + getIcon().paintIcon(this, g, 0, y); + } + + int x = getX() + iconW + 2; + g.setColor(selected ? list.getSelectionForeground() : + list.getForeground()); + if (jsc!=null && !simpleText) { + jsc.rendererText(g, x, g.getFontMetrics().getHeight(), selected); + } + else { + Completion c = jsc!=null ? jsc : nonJavaCompletion; + if (c!=null) { + g.drawString(c.toString(), x, g.getFontMetrics().getHeight()); + } + } + + // Restore rendering hints appropriately. + if (hints!=null) { + if (old instanceof Map) { + g2d.addRenderingHints((Map)old); + } + else { + g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, old); + } + } + else { + g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, old); + } + + } + + + /** + * Sets the background color to use on alternating lines. + * + * @param altBG The new alternate background color. If this is + * null, alternating lines will not use different + * background colors. + * @see #getAlternateBackground() + */ + public static void setAlternateBackground(Color altBG) { + JavaCellRenderer.altBG = altBG; + } + + + /** + * Sets whether to display "simple" text about the completion - just the + * name, no type information, etc. The default value is false. + * + * @param simple Whether to display "simple" text about the completion. + */ + public void setSimpleText(boolean simple) { + simpleText = simple; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/JavaCompletionProvider.java b/src/main/java/org/fife/rsta/ac/bsh/JavaCompletionProvider.java new file mode 100644 index 00000000..7cdcf4f9 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/JavaCompletionProvider.java @@ -0,0 +1,193 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh; + +import java.awt.Point; +import java.io.File; +import java.io.IOException; +import java.util.List; +import javax.swing.text.JTextComponent; + +import org.fife.rsta.ac.ShorthandCompletionCache; +import org.fife.rsta.ac.bsh.buildpath.LibraryInfo; +import org.fife.rsta.ac.bsh.rjc.ast.CompilationUnit; +import org.fife.ui.autocomplete.AbstractCompletionProvider; +import org.fife.ui.autocomplete.Completion; +import org.fife.ui.autocomplete.DefaultCompletionProvider; +import org.fife.ui.autocomplete.LanguageAwareCompletionProvider; +import org.fife.ui.autocomplete.ParameterizedCompletion; + + +/** + * Completion provider for the Java programming language. + * + * @author Robert Futrell + * @version 1.0 + */ +public class JavaCompletionProvider extends LanguageAwareCompletionProvider { + + /** + * The provider used for source code, kept here since it's used so much. + */ + private SourceCompletionProvider sourceProvider; + + private CompilationUnit cu; + + + /** + * Constructor. + */ + public JavaCompletionProvider() { + this(null); + } + + + /** + * Constructor. + * + * @param jarManager The jar manager to use when looking up completion + * choices. This can be passed in to share a single jar manager + * across multiple RSyntaxTextAreas. This may also be + * null, in which case this completion provider will + * have a unique JarManager. + */ + public JavaCompletionProvider(JarManager jarManager) { + + super(new SourceCompletionProvider(jarManager)); + this.sourceProvider = (SourceCompletionProvider) + getDefaultCompletionProvider(); + sourceProvider.setJavaProvider(this); + setShorthandCompletionCache(new JavaShorthandCompletionCache( + sourceProvider, new DefaultCompletionProvider())); + setDocCommentCompletionProvider(new DocCommentCompletionProvider()); + + } + + + /** + * Adds a jar to the "build path." + * + * @param info The jar to add. If this is null, then + * the current JVM's main JRE jar (rt.jar, or classes.jar on OS X) + * will be added. If this jar has already been added, adding it + * again will do nothing (except possibly update its attached source + * location). + * @throws IOException If an IO error occurs. + * @see #removeJar(File) + * @see #getJars() + */ + public void addJar(LibraryInfo info) throws IOException { + sourceProvider.addJar(info); + } + + + /** + * Removes all jars from the "build path." + * + * @see #removeJar(File) + * @see #addJar(LibraryInfo) + * @see #getJars() + */ + public void clearJars() { + sourceProvider.clearJars(); + } + + + /** + * Defers to the source-analyzing completion provider. + * + * @return The already entered text. + */ + @Override + public String getAlreadyEnteredText(JTextComponent comp) { + return sourceProvider.getAlreadyEnteredText(comp); + } + + + public synchronized CompilationUnit getCompilationUnit() { + return cu; + } + + + /** + * {@inheritDoc} + */ + @Override + public List getCompletionsAt(JTextComponent tc, Point p) { + return sourceProvider.getCompletionsAt(tc, p); + } + + + /** + * Returns the jars on the "build path." + * + * @return A list of {@link LibraryInfo}s. Modifying a + * LibraryInfo in this list will have no effect on + * this completion provider; in order to do that, you must re-add + * the jar via {@link #addJar(LibraryInfo)}. If there are + * no jars on the "build path," this will be an empty list. + * @see #addJar(LibraryInfo) + */ + public List getJars() { + return sourceProvider.getJars(); + } + + + /** + * {@inheritDoc} + */ + @Override + public List getParameterizedCompletions( + JTextComponent tc) { + return null; + } + + + /** + * Removes a jar from the "build path." + * + * @param jar The jar to remove. + * @return Whether the jar was removed. This will be false + * if the jar was not on the build path. + * @see #addJar(LibraryInfo) + */ + public boolean removeJar(File jar) { + return sourceProvider.removeJar(jar); + } + + + private void setCommentCompletions(ShorthandCompletionCache shorthandCache) { + AbstractCompletionProvider provider = shorthandCache.getCommentProvider(); + if(provider != null) { + for (Completion c : shorthandCache.getCommentCompletions()) { + provider.addCompletion(c); + } + setCommentCompletionProvider(provider); + } + } + + + public synchronized void setCompilationUnit(CompilationUnit cu) { + this.cu = cu; + } + + + /** + * Set short hand completion cache (template and comment completions) + */ + public void setShorthandCompletionCache(ShorthandCompletionCache cache) { + sourceProvider.setShorthandCache(cache); + //reset comment completions too + setCommentCompletions(cache); + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/JavaLanguageRegistration.java b/src/main/java/org/fife/rsta/ac/bsh/JavaLanguageRegistration.java new file mode 100644 index 00000000..6fa2bf84 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/JavaLanguageRegistration.java @@ -0,0 +1,27 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.fife.rsta.ac.bsh; + +import org.fife.rsta.ac.LanguageSupportRegistration; +import org.fife.ui.rsyntaxtextarea.modes.BshTokenRegistration; + +/** + * + * @author matta + */ +public class JavaLanguageRegistration implements LanguageSupportRegistration { + + @Override + public String getLanguage() { + return BshTokenRegistration.SYNTAX_STYLE; + } + + @Override + public String getLanguageSupportType() { + return JavaLanguageSupport.class.getName(); + } + +} diff --git a/src/main/java/org/fife/rsta/ac/bsh/JavaLanguageSupport.java b/src/main/java/org/fife/rsta/ac/bsh/JavaLanguageSupport.java new file mode 100644 index 00000000..06b087ae --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/JavaLanguageSupport.java @@ -0,0 +1,594 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh; + +import java.awt.Point; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.InputEvent; +import java.awt.event.KeyEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import javax.swing.ActionMap; +import javax.swing.InputMap; +import javax.swing.KeyStroke; +import javax.swing.Timer; +import javax.swing.event.CaretEvent; +import javax.swing.event.CaretListener; +import javax.swing.text.BadLocationException; +import javax.swing.text.Document; +import javax.swing.text.Element; + +import org.fife.rsta.ac.AbstractLanguageSupport; +import org.fife.rsta.ac.GoToMemberAction; +import org.fife.rsta.ac.bsh.rjc.ast.CompilationUnit; +import org.fife.rsta.ac.bsh.rjc.ast.ImportDeclaration; +import org.fife.rsta.ac.bsh.rjc.ast.Package; +import org.fife.rsta.ac.bsh.tree.JavaOutlineTree; +import org.fife.ui.autocomplete.AutoCompletion; +import org.fife.ui.autocomplete.Completion; +import org.fife.ui.rsyntaxtextarea.RSyntaxDocument; +import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; +import org.fife.ui.rsyntaxtextarea.SyntaxConstants; + +/** + * Language support for Java. + * + * @author Robert Futrell + * @version 1.0 + * @see JavaOutlineTree + */ +public class JavaLanguageSupport extends AbstractLanguageSupport { + + /** + * Maps JavaParsers to Info instances about them. + */ + private Map parserToInfoMap; + + /** + * The shared jar manager to use with all {@link JavaCompletionProvider}s, + * or null if each one should have a unique jar manager. + */ + private JarManager jarManager; + + /** + * Client property installed on text areas that points to a listener. + */ + private static final String PROPERTY_LISTENER + = "org.fife.rsta.ac.bsh.JavaLanguageSupport.Listener"; + + /** + * Constructor. + */ + public JavaLanguageSupport() { + parserToInfoMap = new HashMap(); + jarManager = new JarManager(); + setAutoActivationEnabled(true); + setParameterAssistanceEnabled(true); + setShowDescWindow(true); + } + + /** + * Returns the completion provider running on a text area with this Java + * language support installed. + * + * @param textArea The text area. + * @return The completion provider. This will be null if the + * text area does not have this JavaLanguageSupport + * installed. + */ + public JavaCompletionProvider getCompletionProvider( + RSyntaxTextArea textArea) { + AutoCompletion ac = getAutoCompletionFor(textArea); + return (JavaCompletionProvider) ac.getCompletionProvider(); + } + + /** + * Returns the shared jar manager instance. NOTE: This method will be + * removed over time, as the Java support becomes more robust! + * + * @return The shared jar manager. + */ + public JarManager getJarManager() { + return jarManager; + } + + /** + * Returns the Java parser running on a text area with this Java language + * support installed. + * + * @param textArea The text area. + * @return The Java parser. This will be null if the text area + * does not have this JavaLanguageSupport installed. + */ + public JavaParser getParser(RSyntaxTextArea textArea) { + // Could be a parser for another language. + Object parser = textArea.getClientProperty(PROPERTY_LANGUAGE_PARSER); + if (parser instanceof JavaParser) { + return (JavaParser) parser; + } + return null; + } + + /** + * {@inheritDoc} + */ + public void install(RSyntaxTextArea textArea) { + + JavaCompletionProvider p = new JavaCompletionProvider(jarManager); + // Can't use createAutoCompletion(), as Java's is "special." + AutoCompletion ac = new JavaAutoCompletion(p, textArea); + ac.setListCellRenderer(new JavaCellRenderer()); + ac.setAutoCompleteEnabled(isAutoCompleteEnabled()); + ac.setAutoActivationEnabled(isAutoActivationEnabled()); + ac.setAutoActivationDelay(getAutoActivationDelay()); + ac.setExternalURLHandler(new JavadocUrlHandler()); + ac.setParameterAssistanceEnabled(isParameterAssistanceEnabled()); + ac.setParamChoicesRenderer(new JavaParamListCellRenderer()); + ac.setShowDescWindow(getShowDescWindow()); + ac.install(textArea); + installImpl(textArea, ac); + + textArea.setToolTipSupplier(p); + + Listener listener = new Listener(textArea); + textArea.putClientProperty(PROPERTY_LISTENER, listener); + + JavaParser parser = new JavaParser(textArea); + textArea.putClientProperty(PROPERTY_LANGUAGE_PARSER, parser); + textArea.addParser(parser); + textArea.setToolTipSupplier(p); + + Info info = new Info(textArea, p, parser); + parserToInfoMap.put(parser, info); + + installKeyboardShortcuts(textArea); + + textArea.setLinkGenerator(new JavaLinkGenerator(this)); + + } + + /** + * Installs extra keyboard shortcuts supported by this language support. + * + * @param textArea The text area to install the shortcuts into. + */ + private void installKeyboardShortcuts(RSyntaxTextArea textArea) { + + InputMap im = textArea.getInputMap(); + ActionMap am = textArea.getActionMap(); + int c = textArea.getToolkit().getMenuShortcutKeyMask(); + int shift = InputEvent.SHIFT_MASK; + + im.put(KeyStroke.getKeyStroke(KeyEvent.VK_O, c | shift), "GoToType"); + am.put("GoToType", new GoToMemberAction(JavaOutlineTree.class)); + + } + + /** + * {@inheritDoc} + */ + public void uninstall(RSyntaxTextArea textArea) { + + uninstallImpl(textArea); + + JavaParser parser = getParser(textArea); + Info info = parserToInfoMap.remove(parser); + if (info != null) { // Should always be true + parser.removePropertyChangeListener( + JavaParser.PROPERTY_COMPILATION_UNIT, info); + } + textArea.removeParser(parser); + textArea.putClientProperty(PROPERTY_LANGUAGE_PARSER, null); + textArea.setToolTipSupplier(null); + + Object listener = textArea.getClientProperty(PROPERTY_LISTENER); + if (listener instanceof Listener) { // Should always be true + ((Listener) listener).uninstall(); + textArea.putClientProperty(PROPERTY_LISTENER, null); + } + + uninstallKeyboardShortcuts(textArea); + textArea.setLinkGenerator(null); + + } + + /** + * Uninstalls any keyboard shortcuts specific to this language support. + * + * @param textArea The text area to uninstall the actions from. + */ + private void uninstallKeyboardShortcuts(RSyntaxTextArea textArea) { + + InputMap im = textArea.getInputMap(); + ActionMap am = textArea.getActionMap(); + int c = textArea.getToolkit().getMenuShortcutKeyMask(); + int shift = InputEvent.SHIFT_MASK; + + im.remove(KeyStroke.getKeyStroke(KeyEvent.VK_O, c | shift)); + am.remove("GoToType"); + + } + + /** + * Information about an import statement to add and where it should be + * added. This is used internally when a class completion is inserted, and + * it needs an import statement added to the source. + */ + private static class ImportToAddInfo { + + public int offs; + public String text; + + public ImportToAddInfo(int offset, String text) { + this.offs = offset; + this.text = text; + } + + } + + /** + * Manages information about the parsing/auto-completion for a single text + * area. Unlike many simpler language supports, + * JavaLanguageSupport cannot share any information amongst + * instances of RSyntaxTextArea. + */ + private static class Info implements PropertyChangeListener { + + public JavaCompletionProvider provider; + //public JavaParser parser; + + public Info(RSyntaxTextArea textArea, JavaCompletionProvider provider, + JavaParser parser) { + this.provider = provider; + //this.parser = parser; + parser.addPropertyChangeListener( + JavaParser.PROPERTY_COMPILATION_UNIT, this); + } + + /** + * Called when a text area is re-parsed. + * + * @param e The event. + */ + public void propertyChange(PropertyChangeEvent e) { + + String name = e.getPropertyName(); + + if (JavaParser.PROPERTY_COMPILATION_UNIT.equals(name)) { + CompilationUnit cu = (CompilationUnit) e.getNewValue(); +// structureTree.update(file, cu); +// updateTable(); + provider.setCompilationUnit(cu); + } + + } + + } + + /** + * A hack of AutoCompletion that forces the JavaParser + * to re-parse the document when the user presses ctrl+space. + */ + private class JavaAutoCompletion extends AutoCompletion { + + private RSyntaxTextArea textArea; + private String replacementTextPrefix; + + public JavaAutoCompletion(JavaCompletionProvider provider, + RSyntaxTextArea textArea) { + super(provider); + this.textArea = textArea; + } + + private String getCurrentLineText() { + + int caretPosition = textArea.getCaretPosition(); + Element root = textArea.getDocument().getDefaultRootElement(); + int line = root.getElementIndex(caretPosition); + Element elem = root.getElement(line); + int endOffset = elem.getEndOffset(); + int lineStart = elem.getStartOffset(); + + String text = ""; + try { + text = textArea.getText(lineStart, endOffset - lineStart).trim(); + } catch (BadLocationException e) { + e.printStackTrace(); + } + + return text; + + } + + /** + * Overridden to allow for prepending to the replacement text. This + * allows us to insert fully qualified class names. instead of + * unqualified ones, if necessary (i.e. if the user tries to + * auto-complete javax.swing.text.Document, but they've + * explicitly imported org.w3c.dom.Document - we need to + * insert the fully qualified name in that case). + */ + @Override + protected String getReplacementText(Completion c, Document doc, + int start, int len) { + String text = super.getReplacementText(c, doc, start, len); + if (replacementTextPrefix != null) { + text = replacementTextPrefix + text; + replacementTextPrefix = null; + } + return text; + } + + /** + * Determines whether the class name being completed has been imported, + * and if it hasn't, returns the import statement that should be added + * for it. Alternatively, if the class hasn't been imported, but a class + * with the same (unqualified) name HAS been imported, this method sets + * things up so the fully-qualified version of this class's name is + * inserted.

+ * + * Thanks to Guilherme Joao Frantz and Jonatas Schuler for helping with + * the patch! + * + * @param c The completion being inserted. + * @return Whether an import was added. + */ + private ImportToAddInfo getShouldAddImport(ClassCompletion cc) { + + String text = getCurrentLineText(); + + // Make sure we're not currently typing an import statement. + if (!text.startsWith("import ")) { + + JavaCompletionProvider provider = (JavaCompletionProvider) getCompletionProvider(); + CompilationUnit cu = provider.getCompilationUnit(); + int offset = 0; + boolean alreadyImported = false; + + // Try to bail early, if possible. + if (cu == null) { // Can never happen, right? + return null; + } + if ("java.lang".equals(cc.getPackageName())) { + // Package java.lang is "imported" by default. + return null; + } + + String className = cc.getClassName(false); + String fqClassName = cc.getClassName(true); + + // If the completion is in the same package as the source we're + // editing (or both are in the default package), bail. + int lastClassNameDot = fqClassName.lastIndexOf('.'); + boolean ccInPackage = lastClassNameDot > -1; + Package pkg = cu.getPackage(); + if (ccInPackage && pkg != null) { + String ccPkg = fqClassName.substring(0, lastClassNameDot); + String pkgName = pkg.getName(); + if (ccPkg.equals(pkgName)) { + return null; + } + } else if (!ccInPackage && pkg == null) { + return null; + } + + // Loop through all import statements. + Iterator i = cu.getImportIterator(); + for (; i.hasNext();) { + + ImportDeclaration id = i.next(); + offset = id.getNameEndOffset() + 1; + + // Pulling in static methods, etc. from a class - skip + if (id.isStatic()) { + continue; + } // Importing all classes in the package... + else if (id.isWildcard()) { + // NOTE: Class may be in default package... + if (lastClassNameDot > -1) { + String imported = id.getName(); + int dot = imported.lastIndexOf('.'); + String importedPkg = imported.substring(0, dot); + String classPkg = fqClassName.substring(0, lastClassNameDot); + if (importedPkg.equals(classPkg)) { + alreadyImported = true; + break; + } + } + } // Importing a single class from a package... + else { + + String fullyImportedClassName = id.getName(); + int dot = fullyImportedClassName.lastIndexOf('.'); + String importedClassName = fullyImportedClassName. + substring(dot + 1); + + // If they explicitly imported a class with the + // same name, but it's in a different package, then + // the user is required to fully-qualify the class + // in their code (if unqualified, it would be + // assumed to be of the type of the qualified + // class). + if (className.equals(importedClassName)) { + offset = -1; // Means "must fully qualify" + if (fqClassName.equals(fullyImportedClassName)) { + alreadyImported = true; + } + break; + } + + } + + } + + // If the class wasn't imported, we'll need to add an + // import statement! + if (!alreadyImported) { + + StringBuilder importToAdd = new StringBuilder(); + + // If there are no previous imports, add the import + // statement after the package line (if any). + if (offset == 0) { + if (pkg != null) { + offset = pkg.getNameEndOffset() + 1; + // Keep an empty line between package and imports. + importToAdd.append('\n'); + } + } + + // We read through all imports, but didn't find our class. + // Add a new import statement after the last one. + if (offset > -1) { + //System.out.println(classCompletion.getAlreadyEntered(textArea)); + if (offset > 0) { + importToAdd.append("\nimport ").append(fqClassName).append(';'); + } else { + importToAdd.append("import ").append(fqClassName).append(";\n"); + } + // TODO: Determine whether the imports are alphabetical, + // and if so, add the new one alphabetically. + return new ImportToAddInfo(offset, importToAdd.toString()); + } // Otherwise, either the class was imported, or a class + // with the same name was explicitly imported. + else { + // Another class with the same name was imported. + // We must insert the fully-qualified class name + // so the compiler resolves the correct class. + int dot = fqClassName.lastIndexOf('.'); + if (dot > -1) { + String pkgName = fqClassName.substring(0, dot + 1); + replacementTextPrefix = pkgName; + } + } + + } + + } + + return null; + + } + + /** + * Overridden to handle special cases, because sometimes Java code + * completions will edit more in the source file than just the text at + * the current caret position. + */ + @Override + protected void insertCompletion(Completion c, + boolean typedParamListStartChar) { + + ImportToAddInfo importInfo = null; + + // We special-case class completions because they may add import + // statements to the top of our source file. We don't add the + // (possible) new import statement until after the completion is + // inserted; that way, when we treat it as an atomic undo/redo, + // when the user undoes the completion, the caret stays in the + // code instead of jumping to the import. + if (c instanceof ClassCompletion) { + importInfo = getShouldAddImport((ClassCompletion) c); + if (importInfo != null) { + textArea.beginAtomicEdit(); + } + } + + try { + super.insertCompletion(c, typedParamListStartChar); + if (importInfo != null) { + textArea.insert(importInfo.text, importInfo.offs); + } + } finally { + // Be safe and always pair beginAtomicEdit() and endAtomicEdit() + textArea.endAtomicEdit(); + } + + } + + @Override + protected int refreshPopupWindow() { + // Force the parser to re-parse + JavaParser parser = getParser(textArea); + RSyntaxDocument doc = (RSyntaxDocument) textArea.getDocument(); + String style = textArea.getSyntaxEditingStyle(); + parser.parse(doc, style); + return super.refreshPopupWindow(); + } + + } + + /** + * Listens for various events in a text area editing Java (in particular, + * caret events, so we can track the "active" code block). + */ + private class Listener implements CaretListener, ActionListener { + + private RSyntaxTextArea textArea; + private Timer t; + + public Listener(RSyntaxTextArea textArea) { + this.textArea = textArea; + textArea.addCaretListener(this); + t = new Timer(650, this); + t.setRepeats(false); + } + + public void actionPerformed(ActionEvent e) { + + JavaParser parser = getParser(textArea); + if (parser == null) { + return; // Shouldn't happen + } + CompilationUnit cu = parser.getCompilationUnit(); + + // Highlight the line range of the Java method being edited in the + // gutter. + if (cu != null) { // Should always be true + int dot = textArea.getCaretPosition(); + Point p = cu.getEnclosingMethodRange(dot); + if (p != null) { + try { + int startLine = textArea.getLineOfOffset(p.x); + // Unterminated blocks can end in Integer.MAX_VALUE + int endOffs = Math.min(p.y, + textArea.getDocument().getLength()); + int endLine = textArea.getLineOfOffset(endOffs); + textArea.setActiveLineRange(startLine, endLine); + } catch (BadLocationException ble) { + ble.printStackTrace(); + } + } else { + textArea.setActiveLineRange(-1, -1); + } + } + + } + + public void caretUpdate(CaretEvent e) { + t.restart(); + } + + /** + * Should be called whenever Java language support is removed from a + * text area. + */ + public void uninstall() { + textArea.removeCaretListener(this); + } + + } + +} diff --git a/src/main/java/org/fife/rsta/ac/bsh/JavaLinkGenerator.java b/src/main/java/org/fife/rsta/ac/bsh/JavaLinkGenerator.java new file mode 100644 index 00000000..1bc6a96e --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/JavaLinkGenerator.java @@ -0,0 +1,268 @@ +/* + * 02/17/2013 + * + * Copyright (C) 2013 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh; + +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import javax.swing.text.BadLocationException; + +import org.fife.rsta.ac.bsh.rjc.ast.CodeBlock; +import org.fife.rsta.ac.bsh.rjc.ast.CompilationUnit; +import org.fife.rsta.ac.bsh.rjc.ast.FormalParameter; +import org.fife.rsta.ac.bsh.rjc.ast.LocalVariable; +import org.fife.rsta.ac.bsh.rjc.ast.Member; +import org.fife.rsta.ac.bsh.rjc.ast.Method; +import org.fife.rsta.ac.bsh.rjc.ast.TypeDeclaration; +import org.fife.ui.rsyntaxtextarea.LinkGenerator; +import org.fife.ui.rsyntaxtextarea.LinkGeneratorResult; +import org.fife.ui.rsyntaxtextarea.RSyntaxDocument; +import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; +import org.fife.ui.rsyntaxtextarea.RSyntaxUtilities; +import org.fife.ui.rsyntaxtextarea.SelectRegionLinkGeneratorResult; +import org.fife.ui.rsyntaxtextarea.Token; +import org.fife.ui.rsyntaxtextarea.TokenImpl; + + +/** + * Checks for hyperlink-able tokens under the mouse position when Ctrl is + * pressed (Cmd on OS X). Currently this class only checks for accessible + * members in the current file only (e.g. no members in super classes, no other + * classes on the classpath, etc.). So naturally, there is a lot of room for + * improvement. IDE-style applications, for example, would want to check + * for members in super-classes, and open their source on click events. + * + * @author Robert Futrell + * @version 1.0 + */ +// TODO: Anonymous inner classes probably aren't handled well. +class JavaLinkGenerator implements LinkGenerator { + + private JavaLanguageSupport jls; + + + JavaLinkGenerator(JavaLanguageSupport jls) { + this.jls = jls; + } + + + /** + * Checks if the token at the specified offset is possibly a "click-able" + * region. + * + * @param textArea The text area. + * @param offs The offset, presumably at the mouse position. + * @return A result object. + */ + private IsLinkableCheckResult checkForLinkableToken( + RSyntaxTextArea textArea, int offs) { + + IsLinkableCheckResult result = null; + + if (offs>=0) { + + try { + + int line = textArea.getLineOfOffset(offs); + Token first = textArea.getTokenListForLine(line); + RSyntaxDocument doc = (RSyntaxDocument)textArea.getDocument(); + Token prev = null; + + for (Token t=first; t!=null && t.isPaintable(); t=t.getNextToken()) { + + if (t.containsPosition(offs)) { + + // RSTA's tokens are pooled and re-used, so we must + // defensively make a copy of the one we want to keep! + Token token = new TokenImpl(t); + boolean isMethod = false; + + if (prev==null) { + prev = RSyntaxUtilities.getPreviousImportantToken( + doc, line-1); + } + if (prev!=null && prev.isSingleChar('.')) { + // Not a field or method defined in this class. + break; + } + + Token next = RSyntaxUtilities.getNextImportantToken( + t.getNextToken(), textArea, line); + if (next!=null && next.isSingleChar(Token.SEPARATOR, '(')) { + isMethod = true; + } + + result = new IsLinkableCheckResult(token, isMethod); + break; + + } + + else if (!t.isCommentOrWhitespace()) { + prev = t; + } + + } + + } catch (BadLocationException ble) { + ble.printStackTrace(); // Never happens + } + + } + + return result; + + } + + + /** + * {@inheritDoc} + */ + public LinkGeneratorResult isLinkAtOffset(RSyntaxTextArea textArea, + int offs) { + + int start = -1; + int end = -1; + + IsLinkableCheckResult result = checkForLinkableToken(textArea, offs); + if (result!=null) { + + JavaParser parser = jls.getParser(textArea); + CompilationUnit cu = parser.getCompilationUnit(); + Token t = result.token; + boolean method = result.method; + + if (cu!=null) { + + TypeDeclaration td = cu.getDeepestTypeDeclarationAtOffset(offs); + boolean staticFieldsOnly = false; + boolean deepestTypeDec = true; + boolean deepestContainingMemberStatic = false; + while (td!=null && start==-1) { + + // First, check for a local variable in methods/static blocks + if (!method && deepestTypeDec) { + + Iterator i = td.getMemberIterator(); + while (i.hasNext()) { + + Method m = null; // Nasty! Clean this code up + Member member = i.next(); + CodeBlock block = null; + + // Check if a method or static block contains offs + if (member instanceof Method) { + m = (Method)member; + if (m.getBodyContainsOffset(offs) && m.getBody()!=null) { + deepestContainingMemberStatic = m.isStatic(); + block = m.getBody().getDeepestCodeBlockContaining(offs); + } + } + else if (member instanceof CodeBlock) { + block = (CodeBlock)member; + deepestContainingMemberStatic = block.isStatic(); + block = block.getDeepestCodeBlockContaining(offs); + } + + // If so, scan its locals + if (block!=null) { + String varName = t.getLexeme(); + // Local variables first, in reverse order + List locals = block.getLocalVarsBefore(offs); + Collections.reverse(locals); + for (LocalVariable local : locals) { + if (varName.equals(local.getName())) { + start = local.getNameStartOffset(); + end = local.getNameEndOffset(); + } + } + // Then arguments, if any. + if (start==-1 && m!=null) { + for (int j=0; j i = method ? + td.getMethodIterator() : td.getFieldIterator(); + while (i.hasNext()) { + Member member = i.next(); + if (((!deepestContainingMemberStatic && !staticFieldsOnly) || member.isStatic()) && + varName.equals(member.getName())) { + start = member.getNameStartOffset(); + end = member.getNameEndOffset(); + break; + } + } + } + + // If still no match found, check parent type + if (start==-1) { + staticFieldsOnly |= td.isStatic(); + //td = td.isStatic() ? null : td.getParentType(); + td = td.getParentType(); + // Don't check for local vars in parent type methods. + deepestTypeDec = false; + } + + } + + } + + if (start>-1) { + return new SelectRegionLinkGeneratorResult(textArea, t.getOffset(), + start, end); + } + + } + + return null; + + } + + + /** + * The result of checking whether a region of code under the mouse is + * possibly link-able. + */ + private static class IsLinkableCheckResult { + + /** + * The token under the mouse position. + */ + private Token token; + + /** + * Whether the token is a method invocation (as opposed to a local + * variable or field). + */ + private boolean method; + + private IsLinkableCheckResult(Token token, boolean method) { + this.token = token; + this.method = method; + } + + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/JavaParamListCellRenderer.java b/src/main/java/org/fife/rsta/ac/bsh/JavaParamListCellRenderer.java new file mode 100644 index 00000000..c2196ddc --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/JavaParamListCellRenderer.java @@ -0,0 +1,69 @@ +/* + * 12/16/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh; + +import java.awt.Component; +import java.awt.Dimension; +import javax.swing.JList; + + +/** + * The renderer used for parameter completions (for methods) in Java. + * + * @author Robert Futrell + * @version 1.0 + */ +public class JavaParamListCellRenderer extends JavaCellRenderer { + + + public JavaParamListCellRenderer() { + // Param completions don't display type info, etc., because all + // completions for a single parameter have the same type (or subclass + // that type). + setSimpleText(true); + } + + + /** + * Returns the preferred size of a particular cell. Note that the parent + * class {@link JavaCellRenderer} doesn't override this method, because + * it doesn't use the cells to dictate the preferred size of the list, due + * to the large number of completions it shows at a time. + */ + @Override + public Dimension getPreferredSize() { + Dimension d = super.getPreferredSize(); + d.width += 32; // Looks better when less scrunched. + return d; + } + + + /** + * Returns the renderer. + * + * @param list The list of choices being rendered. + * @param value The {@link Completion} being rendered. + * @param index The index into list being rendered. + * @param selected Whether the item is selected. + * @param hasFocus Whether the item has focus. + */ + @Override + public Component getListCellRendererComponent(JList list, Object value, + int index, boolean selected, boolean hasFocus) { + super.getListCellRendererComponent(list, value, index, selected, + hasFocus); + JavaSourceCompletion ajsc = (JavaSourceCompletion)value; + setIcon(ajsc.getIcon()); + return this; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/JavaParser.java b/src/main/java/org/fife/rsta/ac/bsh/JavaParser.java new file mode 100644 index 00000000..f1e692c0 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/JavaParser.java @@ -0,0 +1,164 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh; + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.io.IOException; +import javax.swing.text.Element; + +import org.fife.io.DocumentReader; +import org.fife.rsta.ac.bsh.rjc.ast.CompilationUnit; +import org.fife.rsta.ac.bsh.rjc.lexer.Scanner; +import org.fife.rsta.ac.bsh.rjc.notices.ParserNotice; +import org.fife.rsta.ac.bsh.rjc.parser.ASTFactory; +import org.fife.ui.rsyntaxtextarea.RSyntaxDocument; +import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; +import org.fife.ui.rsyntaxtextarea.parser.AbstractParser; +import org.fife.ui.rsyntaxtextarea.parser.DefaultParseResult; +import org.fife.ui.rsyntaxtextarea.parser.DefaultParserNotice; +import org.fife.ui.rsyntaxtextarea.parser.ParseResult; + + +/** + * Parses Java code in an RSyntaxTextArea.

+ * + * Like all RSTA Parsers, a JavaParser instance is notified + * when the RSTA's text content changes. After a small delay, it will parse + * the content as Java code, building an AST and looking for any errors. When + * parsing is complete, a property change event of type + * {@link #PROPERTY_COMPILATION_UNIT} is fired. Listeners can check the new + * value of the property for the {@link CompilationUnit} built that represents + * the source code in the text area. Note that the CompilationUnit + * may be incomplete if there were parsing/syntax errors (it will usually be + * complete "up to" the error in the content).

+ * + * This parser cannot be shared amongst multiple instances of + * RSyntaxTextArea.

+ * + * Please keep in mind that this class is a work-in-progress! + * + * @author Robert Futrell + * @version 0.5 + */ +public class JavaParser extends AbstractParser { + + /** + * The property change event that's fired when the document is re-parsed. + * Applications can listen for this property change and update themselves + * accordingly. + */ + public static final String PROPERTY_COMPILATION_UNIT = "CompilationUnit"; + + private CompilationUnit cu; + private PropertyChangeSupport support; + private DefaultParseResult result; + + + /** + * Constructor. + */ + public JavaParser(RSyntaxTextArea textArea) { + support = new PropertyChangeSupport(this); + result = new DefaultParseResult(this); + } + + + /** + * Adds all notices from the Java parser to the results object. + */ + private void addNotices(RSyntaxDocument doc) { + + result.clearNotices(); + int count = cu==null ? 0 : cu.getParserNoticeCount(); + + if (count==0) { + return; + } + + for (int i=0; i-1) { + int len = notice.getLength(); + result.addNotice(new DefaultParserNotice(this, + notice.getMessage(), notice.getLine(), offs, len)); + } + } + + } + + + public void addPropertyChangeListener(String prop, PropertyChangeListener l) { + support.addPropertyChangeListener(prop, l); + } + + + /** + * Returns the compilation unit from the last time the text area was + * parsed. + * + * @return The compilation unit, or null if it hasn't yet + * been parsed or an unexpected error occurred while parsing. + */ + public CompilationUnit getCompilationUnit() { + return cu; + } + + + public int getOffset(RSyntaxDocument doc, ParserNotice notice) { + Element root = doc.getDefaultRootElement(); + Element elem = root.getElement(notice.getLine()); + int offs = elem.getStartOffset() + notice.getColumn(); + return offs>=elem.getEndOffset() ? -1 : offs; + } + + + /** + * {@inheritDoc} + */ + public ParseResult parse(RSyntaxDocument doc, String style) { + + cu = null; + result.clearNotices(); + // Always spell check all lines, for now. + int lineCount = doc.getDefaultRootElement().getElementCount(); + result.setParsedLines(0, lineCount-1); + + DocumentReader r = new DocumentReader(doc); + Scanner scanner = new Scanner(r); + scanner.setDocument(doc); + ASTFactory fact = new ASTFactory(); + long start = System.currentTimeMillis(); + try { + cu = fact.getCompilationUnit("SomeFile.java", scanner); // TODO: Real name? + long time = System.currentTimeMillis() - start; + result.setParseTime(time); + } catch (IOException ioe) { + result.setError(ioe); +// ioe.printStackTrace(); + } + + r.close(); + + addNotices(doc); + support.firePropertyChange(PROPERTY_COMPILATION_UNIT, null, cu); + return result; + + } + + + public void removePropertyChangeListener(String prop, PropertyChangeListener l) { + support.removePropertyChangeListener(prop, l); + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/JavaShorthandCompletion.java b/src/main/java/org/fife/rsta/ac/bsh/JavaShorthandCompletion.java new file mode 100644 index 00000000..ae3bed1b --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/JavaShorthandCompletion.java @@ -0,0 +1,110 @@ +/* + * 04/08/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh; + +import java.awt.Color; +import java.awt.Graphics; +import javax.swing.Icon; + +import org.fife.ui.autocomplete.CompletionProvider; +import org.fife.ui.autocomplete.ShorthandCompletion; + + +/** + * A completion for shorthand items that mimics the style seen in Eclipse. + * + * @author Robert Futrell + * @version 1.0 + */ +class JavaShorthandCompletion extends ShorthandCompletion implements + JavaSourceCompletion { + + private static final Color SHORTHAND_COLOR = new Color(0, 127, 174); + + + /** + * Constructor. + * + * @param provider + * @param inputText + * @param replacementText + */ + public JavaShorthandCompletion(CompletionProvider provider, + String inputText, String replacementText) { + super(provider, inputText, replacementText); + } + + + /** + * Constructor. + * + * @param provider + * @param inputText + * @param replacementText + * @param shortDesc + */ + public JavaShorthandCompletion(CompletionProvider provider, + String inputText, String replacementText, String shortDesc) { + super(provider, inputText, replacementText, shortDesc); + } + + + /** + * {@inheritDoc} + */ + @Override + public Icon getIcon() { + return IconFactory.get().getIcon(IconFactory.TEMPLATE_ICON); + } + + + /** + * {@inheritDoc} + */ + public void rendererText(Graphics g, int x, int y, boolean selected) { + renderText(g, getInputText(), getReplacementText(), x, y, selected); + } + + + /** + * Renders a completion in the style of a short-hand completion. + * + * @param g The graphics context. + * @param input The text the user enters to display this completion. + * @param shortDesc An optional short description of the completion. + * @param x The x-offset at which to paint. + * @param y The y-offset at which to paint. + * @param selected Whether this completion choice is selected. + */ + public static void renderText(Graphics g, String input, String shortDesc, + int x, int y, boolean selected) { + Color orig = g.getColor(); + if (!selected && shortDesc!=null) { + g.setColor(SHORTHAND_COLOR); + } + g.drawString(input, x, y); + if (shortDesc!=null) { + x += g.getFontMetrics().stringWidth(input); + if (!selected) { + g.setColor(orig); + } + String temp = " - "; + g.drawString(temp, x, y); + x += g.getFontMetrics().stringWidth(temp); + if (!selected) { + g.setColor(Color.GRAY); + } + g.drawString(shortDesc, x, y); + } + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/JavaShorthandCompletionCache.java b/src/main/java/org/fife/rsta/ac/bsh/JavaShorthandCompletionCache.java new file mode 100644 index 00000000..819a88e5 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/JavaShorthandCompletionCache.java @@ -0,0 +1,95 @@ +/* + * 07/22/2012 + * + * Copyright (C) 2012 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh; + +import java.util.ResourceBundle; + +import org.fife.rsta.ac.ShorthandCompletionCache; +import org.fife.ui.autocomplete.BasicCompletion; +import org.fife.ui.autocomplete.DefaultCompletionProvider; + + +/** + * A cache of basic template and comment completions for Java, e.g. + * System.out.println(). + * + * @see ShorthandCompletionCache + * @author Steve + */ +public class JavaShorthandCompletionCache extends ShorthandCompletionCache { + + private static final String MSG = "org.fife.rsta.ac.bsh.resources"; + private static final ResourceBundle msg = ResourceBundle.getBundle(MSG); + + public JavaShorthandCompletionCache(DefaultCompletionProvider + templateProvider, DefaultCompletionProvider commentsProvider) { + + super(templateProvider, commentsProvider); + String template = null; + + //load defaults + template = "System.out.println(${});${cursor}"; + addShorthandCompletion(new JavaTemplateCompletion(templateProvider, "sysout", "sysout", template, + msg.getString("sysout.shortDesc"), msg.getString("sysout.summary"))); + + template = "System.err.println(${});${cursor}"; + addShorthandCompletion(new JavaTemplateCompletion(templateProvider, "syserr", "syserr", template, + msg.getString("syserr.shortDesc"), msg.getString("syserr.summary"))); + + template = + "for (int ${i} = 0; ${i} < ${array}.length; ${i}++) {\n\t${cursor}\n}"; + addShorthandCompletion(new JavaTemplateCompletion(templateProvider, "for", "for-loop-array", template, + msg.getString("for.array.shortDesc"), msg.getString("for.array.summary"))); + + template = "for (int ${i} = 0; ${i} < ${10}; ${i}++) {\n\t${cursor}\n}"; + addShorthandCompletion(new JavaTemplateCompletion(templateProvider, "for", "for-loop", + template, msg.getString("for.loop.shortDesc"), msg.getString("for.loop.summary"))); + + template = "if (${condition}) {\n\t${cursor}\n}"; + addShorthandCompletion(new JavaTemplateCompletion(templateProvider, "if", "if-cond", + template, msg.getString("if.cond.shortDesc"), msg.getString("if.cond.summary"))); + + template = "if (${condition}) {\n\t${cursor}\n}\nelse {\n\t\n}"; + addShorthandCompletion(new JavaTemplateCompletion(templateProvider, "if", "if-else", + template, msg.getString("if.else.shortDesc"), msg.getString("if.else.summary"))); + + template = "do {\n\t${cursor}\n} while (${condition});"; + addShorthandCompletion(new JavaTemplateCompletion(templateProvider, "do", "do-loop", template, + msg.getString("do.shortDesc"), msg.getString("do.summary"))); + + template = "while (${condition}) {\n\t${cursor}\n}"; + addShorthandCompletion(new JavaTemplateCompletion(templateProvider, "while", "while-cond", + template, msg.getString("while.shortDesc"), msg.getString("while.summary"))); + + template = "new Runnable() {\n\tpublic void run() {\n\t\t${cursor}\n\t}\n}"; + addShorthandCompletion(new JavaTemplateCompletion(templateProvider, "runnable", "runnable", template, + msg.getString("runnable.shortDesc"))); + + template = "switch (${key}) {\n\tcase ${value}:\n\t\t${cursor}\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n}"; + addShorthandCompletion(new JavaTemplateCompletion(templateProvider, "switch", "switch-statement", + template, msg.getString("switch.case.shortDesc"), msg.getString("switch.case.summary"))); + + template = "try {\n\t ${cursor} \n} catch (${err}) {\n\t\n}"; + addShorthandCompletion(new JavaTemplateCompletion(templateProvider, "try", "try-catch", + template, msg.getString("try.catch.shortDesc"), msg.getString("try.catch.summary"))); + + template = "catch (${err}) {\n\t${cursor}\n}"; + addShorthandCompletion(new JavaTemplateCompletion(templateProvider, "catch", "catch-block", + template, msg.getString("catch.block.shortDesc"), msg.getString("catch.block.summary"))); + + /** Comments **/ + addCommentCompletion(new BasicCompletion(commentsProvider, "TODO:", null, msg.getString("todo"))); + addCommentCompletion(new BasicCompletion(commentsProvider, "FIXME:", null, msg.getString("fixme"))); + + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/JavaSourceCompletion.java b/src/main/java/org/fife/rsta/ac/bsh/JavaSourceCompletion.java new file mode 100644 index 00000000..d536aff5 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/JavaSourceCompletion.java @@ -0,0 +1,45 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh; + +import java.awt.Graphics; + +import org.fife.ui.autocomplete.Completion; + + +/** + * Interface for Java source code completions. + * + * @author Robert Futrell + * @version 1.0 + */ +public interface JavaSourceCompletion extends Completion { + + + /** + * Force subclasses to override equals(). + * TODO: Remove me + */ + public boolean equals(Object obj); + + + /** + * Used by {@link JavaCellRenderer} to render this completion choice. + * + * @param g + * @param x + * @param y + * @param selected + */ + public void rendererText(Graphics g, int x, int y, boolean selected); + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/JavaTemplateCompletion.java b/src/main/java/org/fife/rsta/ac/bsh/JavaTemplateCompletion.java new file mode 100644 index 00000000..6b00b082 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/JavaTemplateCompletion.java @@ -0,0 +1,70 @@ +/* + * 06/25/2012 + * + * Copyright (C) 2012 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh; + +import java.awt.Graphics; +import javax.swing.Icon; + +import org.fife.ui.autocomplete.CompletionProvider; +import org.fife.ui.autocomplete.TemplateCompletion; + + +/** + * A template completion for Java. + * + * @author Robert Futrell + * @version 1.0 + */ +public class JavaTemplateCompletion extends TemplateCompletion + implements JavaSourceCompletion { + + private String icon; + + + public JavaTemplateCompletion(CompletionProvider provider, + String inputText, String definitionString, String template) { + this(provider, inputText, definitionString, template, null); + } + + + public JavaTemplateCompletion(CompletionProvider provider, + String inputText, String definitionString, String template, + String shortDesc) { + this(provider, inputText, definitionString, template, shortDesc, null); + } + + + public JavaTemplateCompletion(CompletionProvider provider, + String inputText, String definitionString, String template, + String shortDesc, String summary) { + super(provider, inputText, definitionString, template, shortDesc, summary); + setIcon(IconFactory.TEMPLATE_ICON); + } + + + @Override + public Icon getIcon() { + return IconFactory.get().getIcon(icon); + } + + + public void rendererText(Graphics g, int x, int y, boolean selected) { + JavaShorthandCompletion.renderText(g, getInputText(), + getShortDescription(), x, y, selected); + } + + + public void setIcon(String iconId) { + this.icon = iconId; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/JavadocUrlHandler.java b/src/main/java/org/fife/rsta/ac/bsh/JavadocUrlHandler.java new file mode 100644 index 00000000..d461703c --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/JavadocUrlHandler.java @@ -0,0 +1,371 @@ +/* + * 05/09/2012 + * + * Copyright (C) 2012 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh; + +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.List; +import javax.swing.UIManager; +import javax.swing.event.HyperlinkEvent; + +import org.fife.rsta.ac.LanguageSupportFactory; +import org.fife.rsta.ac.bsh.classreader.ClassFile; +import org.fife.rsta.ac.bsh.classreader.FieldInfo; +import org.fife.rsta.ac.bsh.classreader.MethodInfo; +import org.fife.ui.autocomplete.Completion; +import org.fife.ui.autocomplete.DescWindowCallback; +import org.fife.ui.autocomplete.ExternalURLHandler; +import org.fife.ui.autocomplete.Util; +import org.fife.ui.rsyntaxtextarea.modes.JavaTokenRegistration; + + +/** + * Handles hyperlinks that are clicked in Javadoc for code completions. It's + * assumed that the links found were created via + * {@link org.fife.rsta.ac.bsh.Util#docCommentToHtml(String)}, so that things + * such as "@see" links are interpreted properly. + * + * @author Robert Futrell + * @version 1.0 + */ +public class JavadocUrlHandler implements ExternalURLHandler { + + + /** + * Returns the parent package backupCount levels up from + * the package specified. + * + * @param pkg A package. + * @param backupCount The number of packages "up" to go. + * @return The parent package. + */ + private String doBackups(String pkg, int backupCount) { + int lastDot = pkg.length(); + while (lastDot>-1 && backupCount>0) { + lastDot = pkg.lastIndexOf('.', lastDot); + backupCount--; + } + return lastDot>-1 ? pkg.substring(0, lastDot) : ""; + } + + + /** + * Returns the Java language support. + * + * @return The Java language support + */ + private JavaLanguageSupport getJavaLanguageSupport() { + return (JavaLanguageSupport)LanguageSupportFactory.get(). + getSupportFor(JavaTokenRegistration.SYNTAX_STYLE); + } + + + /** + * Returns the anchor portion of a (relative) URL. + * + * @param url The URL. + * @return The anchor, or null if none. + */ + private static final String getAnchor(String url) { + int pound = url.indexOf('#'); + return pound>-1 ? url.substring(pound+1) : null; + } + + + /** + * Gets the arguments from a method signature. + * + * @param methodSignature The method signature. + * @return The arguments, or an empty array if none. + */ + private static final String[] getArgs(String methodSignature) { + + String[] args = null; + + int lparen = methodSignature.indexOf('('); + if (lparen>-1) { + int rparen = methodSignature.indexOf(')', lparen); // Should be len-1 + if (rparen>-1 && rparen>lparen+1) { + String temp = methodSignature.substring(lparen, rparen); + args = temp.split("\\s*,\\s*"); + } + } + + if (args==null) { + args = new String[0]; + } + return args; + + } + + + /** + * Returns the class for a completion (class completions return the class + * itself, member completions return the enclosing class). + */ + private String getClass(Completion c, String desc) { + + String clazz = null; + + if (c instanceof ClassCompletion) { + clazz = ((ClassCompletion)c).getClassName(true); + } + else if (c instanceof MemberCompletion) { + MemberCompletion mc = (MemberCompletion)c; + clazz = mc.getEnclosingClassName(true); + } + else { + System.err.println("Can't determine class from completion type: " + + c.getClass() + " (" + c.toString() + ") - href: " + desc); + } + + return clazz; + + } + + + /** + * Returns the package of the specified completion. + * + * @param c The completion. + * @param desc The description text being parsed. Used for errors if we + * cannot determine the package. + * @return The package. + */ + private String getPackage(Completion c, String desc) { + + String pkg = null; + + if (c instanceof ClassCompletion) { + pkg = ((ClassCompletion)c).getPackageName(); + } + else if (c instanceof MemberCompletion) { + String definedIn = ((MemberCompletion)c).getEnclosingClassName(true); + if (definedIn!=null) { + int lastDot = definedIn.lastIndexOf('.'); + if (lastDot>-1) { + pkg = definedIn.substring(0, lastDot); + } + } + } + else { + System.err.println("Can't determine package from completion type: " + + c.getClass() + " (" + c.toString() + ") - href: " + desc); + } + + return pkg; + + } + + + /** + * Returns whether the text is a relative URL to other Javadoc. + * + * @param text A link in Javadoc. + * @return Whether the link is a relative path to more Javadoc. + */ + private boolean isRelativeUrl(String text) { + // Javadoc is always ".html", and we support full URL's elsewhere. + final String[] EXTS = { ".html", ".htm" }; + for (int i=0; i-1 || + text.indexOf(EXTS[i]+"?")>-1) { + return true; + } + } + return false; + } + + + /** + * {@inheritDoc} + */ + public void urlClicked(HyperlinkEvent e, Completion c, + DescWindowCallback callback) { + + // A "real" URL (starts with http://, for example) should be opened + // in the system browser, not the completion description window. + URL url = e.getURL(); + if (url!=null) { + // Try loading in external browser (Java 6+ only). + try { + Util.browse(new URI(url.toString())); + } catch (/*IO*/URISyntaxException ioe) { + UIManager.getLookAndFeel().provideErrorFeedback(null); + ioe.printStackTrace(); + } + return; + } + + // A relative path URL (no leading "http://") results in a null URL. + // Class should be in the same package as the one we're currently + // viewing. Example: java.lang.String class documentation + String desc = e.getDescription(); + //System.out.println(desc); + if (desc!=null) { + + if (isRelativeUrl(desc)) { + int ext = desc.indexOf(".htm"); + if (ext>-1) { + + // Could be link. A + // popular href format is "../../util/Formatter.html#syntax". + // We must determine "relative" package location. + String anchor = getAnchor(desc); + String clazz = desc.substring(0, ext); + int backups = 0; + while (clazz.startsWith("../")) { + backups++; + clazz = clazz.substring(3); + } + clazz = clazz.replace('/', '.'); + + String pkg = getPackage(c, desc); + if (pkg!=null) { + clazz = doBackups(pkg, backups) + "." + clazz; + JavaLanguageSupport jls = getJavaLanguageSupport(); + ClassFile cf = jls.getJarManager().getClassEntry(clazz); + if (cf!=null) { + ClassCompletion cc = new ClassCompletion(c.getProvider(), cf); + callback.showSummaryFor(cc, anchor); + } + } + + } + } + + // Could be format "com.mycompany.pkg.MyClass", with optional + // #method() (for example, @see's). + else { + + JavaLanguageSupport jls = getJavaLanguageSupport(); + + String clazz = desc; + String member = null; + int pound = desc.indexOf('#'); + if (pound>-1) { // TODO: Handle properly + member = clazz.substring(pound+1); + clazz = clazz.substring(0, pound); + } + + // Just a class name, i.e. "String", "java.util.regex.Pattern". + if (member==null) { + boolean guessedPackage = false; + if (clazz.indexOf('.')==-1) { + String pkg = getPackage(c, desc); + if (pkg!=null) { + clazz = pkg + "." + clazz; + } + guessedPackage = true; + } + ClassFile cf = jls.getJarManager().getClassEntry(clazz); + if (cf==null && guessedPackage) { + // Wasn't in the same package as "c", try java.lang + int lastDot = clazz.lastIndexOf('.'); + clazz = "java.lang." + clazz.substring(lastDot+1); + cf = jls.getJarManager().getClassEntry(clazz); + } + if (cf!=null) { + ClassCompletion cc = new ClassCompletion(c.getProvider(), cf); + callback.showSummaryFor(cc, null); + } + else { + UIManager.getLookAndFeel().provideErrorFeedback(null); + System.err.println("Unknown class: " + clazz); + } + } + + // Member specified, such as "String#format(...)", + // "java.util.regex.Pattern.compile(...)", or "#method()". + else { + + boolean guessedPackage = false; + + if (pound==0) { // Member of this class (i.e. "#foobar(bas)") + // "clazz" was incorrect previously in this case + clazz = getClass(c, desc); + } + else { // i.e. "String#CASE_INSENSITIVE_ORDER" + // If no package specified, assume clazz is in the same + // package as the currently displayed completion. + if (clazz.indexOf('.')==-1) { + String pkg = getPackage(c, desc); + if (pkg!=null) { + clazz = pkg + "." + clazz; + } + guessedPackage = true; + } + } + + ClassFile cf = jls.getJarManager().getClassEntry(clazz); + if (cf==null && guessedPackage) { + // Wasn't in the same package as "c", try java.lang + int lastDot = clazz.lastIndexOf('.'); + clazz = "java.lang." + clazz.substring(lastDot+1); + cf = jls.getJarManager().getClassEntry(clazz); + } + if (cf!=null) { + + Completion memberCompletion = null; + + int lparen = member.indexOf('('); + if (lparen==-1) { // A field, or method with args omitted + FieldInfo fi = cf.getFieldInfoByName(member); + if (fi!=null) { // Try fields first, it's most likely + memberCompletion = new FieldCompletion(c.getProvider(), fi); + } + else { // Try methods second + List miList = cf.getMethodInfoByName(member, -1); + if (miList!=null && miList.size()>0) { + MethodInfo mi = miList.get(0);// Just show the first if multiple + memberCompletion = new MethodCompletion(c.getProvider(), mi); + } + } + } + + else { + String[] args = getArgs(member); + String methodName = member.substring(0, lparen); + List miList = cf.getMethodInfoByName(methodName, args.length); + if (miList!=null && miList.size()>0) { + if (miList.size()>1) { + // TODO: Pick correct overload based on args + System.err.println("Multiple overload support not yet implemented"); + } + else { + MethodInfo mi = miList.get(0); + memberCompletion = new MethodCompletion(c.getProvider(), mi); + } + } + } + + if (memberCompletion!=null) { + callback.showSummaryFor(memberCompletion, null); + } + + } + else { + UIManager.getLookAndFeel().provideErrorFeedback(null); + System.err.println("Unknown class: " + clazz + + " (href: " + desc + ")"); + } + + } + + } + + } + + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/LocalVariableCompletion.java b/src/main/java/org/fife/rsta/ac/bsh/LocalVariableCompletion.java new file mode 100644 index 00000000..a5672e82 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/LocalVariableCompletion.java @@ -0,0 +1,73 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh; + +import java.awt.Graphics; +import javax.swing.Icon; + +import org.fife.rsta.ac.bsh.rjc.ast.LocalVariable; +import org.fife.ui.autocomplete.CompletionProvider; + +class LocalVariableCompletion extends AbstractJavaSourceCompletion { + + private LocalVariable localVar; + + /** + * The relevance of local variables. This allows local variables to be + * "higher" in the completion list than other types. + */ + private static final int RELEVANCE = 4; + + + public LocalVariableCompletion(CompletionProvider provider, + LocalVariable localVar) { + super(provider, localVar.getName()); + this.localVar = localVar; + setRelevance(RELEVANCE); + } + + + @Override + public boolean equals(Object obj) { + return (obj instanceof LocalVariableCompletion) && + ((LocalVariableCompletion)obj).getReplacementText(). + equals(getReplacementText()); + } + + + @Override + public Icon getIcon() { + return IconFactory.get().getIcon(IconFactory.LOCAL_VARIABLE_ICON); + } + + + @Override + public String getToolTipText() { + return localVar.getType() + " " + localVar.getName(); + } + + + @Override + public int hashCode() { + return getReplacementText().hashCode(); // Match equals() + } + + + public void rendererText(Graphics g, int x, int y, boolean selected) { + StringBuilder sb = new StringBuilder(); + sb.append(localVar.getName()); + sb.append(" : "); + sb.append(localVar.getType()); + g.drawString(sb.toString(), x, y); + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/MemberCompletion.java b/src/main/java/org/fife/rsta/ac/bsh/MemberCompletion.java new file mode 100644 index 00000000..abef594f --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/MemberCompletion.java @@ -0,0 +1,111 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh; + +import org.fife.rsta.ac.bsh.IconFactory.IconData; + + +/** + * Extra methods defined by a completion for a Java member (fields and methods). + * + * @author Robert Futrell + * @version 1.0 + */ +interface MemberCompletion extends JavaSourceCompletion { + + + /** + * Returns the name of the enclosing class. + * + * @param fullyQualified Whether the name returned should be fully + * qualified. + * @return The class name. + */ + public String getEnclosingClassName(boolean fullyQualified); + + + /** + * Returns the signature of this member. + * + * @return The signature. + */ + public String getSignature(); + + + /** + * Returns the type of this member (the return type for methods). + * + * @return The type of this member. + */ + public String getType(); + + + /** + * Returns whether this member is deprecated. + * + * @return Whether this member is deprecated. + */ + public boolean isDeprecated(); + + + /** + * Meta data about the member. Member completions will be constructed + * from a concrete instance of this interface. This is because there are + * two sources that member completions come from - parsing Java source + * files and parsing compiled class files (in libraries). + */ + public static interface Data extends IconData { + + /** + * Returns the name of the enclosing class. + * + * @param fullyQualified Whether the name returned should be fully + * qualified. + * @return The class name. + */ + public String getEnclosingClassName(boolean fullyQualified); + + /** + * Returns the signature of this member. + * + * @return The signature. + * @see MemberCompletion#getSignature() + */ + public String getSignature(); + + /** + * Returns the summary description (should be HTML) for this member. + * + * @return The summary description, or null if there is + * none. + * @see MemberCompletion#getSummary() + */ + public String getSummary(); + + /** + * Returns the type of this member (the return type for methods). + * + * @return The type of this member. + * @see MemberCompletion#getType() + */ + public String getType(); + + /** + * Returns whether this member is a constructor. + * + * @return Whether this member is a constructor. + */ + public boolean isConstructor(); + + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/MethodCompletion.java b/src/main/java/org/fife/rsta/ac/bsh/MethodCompletion.java new file mode 100644 index 00000000..8ba5fda4 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/MethodCompletion.java @@ -0,0 +1,332 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh; + +import java.awt.Color; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.util.ArrayList; +import java.util.List; +import javax.swing.Icon; +import javax.swing.text.JTextComponent; + +import org.fife.rsta.ac.bsh.classreader.MethodInfo; +import org.fife.rsta.ac.bsh.rjc.ast.FormalParameter; +import org.fife.rsta.ac.bsh.rjc.ast.Method; +import org.fife.rsta.ac.bsh.rjc.lang.Type; +import org.fife.ui.autocomplete.Completion; +import org.fife.ui.autocomplete.CompletionProvider; +import org.fife.ui.autocomplete.FunctionCompletion; + + +/** + * A completion for a Java method. This completion gets its information from + * one of two sources: + * + *

+ * + * @author Robert Futrell + * @version 1.0 + */ +class MethodCompletion extends FunctionCompletion implements MemberCompletion { + + /** + * The data source for our completion attributes. + */ + private Data data; + + /** + * Used to compare this method completion with another. + */ + private String compareString; + + /** + * The relevance of methods. This allows methods to be "higher" in + * the completion list than other types. + */ + private static final int NON_CONSTRUCTOR_RELEVANCE = 2; + + + /** + * Creates a completion for a method discovered when parsing a Java + * source file. + * + * @param provider + * @param m Meta data about the method. + */ + public MethodCompletion(CompletionProvider provider, Method m) { + + // NOTE: "void" might not be right - I think this might be constructors + super(provider, m.getName(), m.getType()==null ? "void" : m.getType().toString()); + setDefinedIn(m.getParentTypeDeclaration().getName()); + this.data = new MethodData(m); + setRelevanceAppropriately(); + + int count = m.getParameterCount(); + List params = new ArrayList(count); + for (int i=0; i params = new ArrayList(paramTypes.length); + for (int i=0; iCompletion to compare to. + * @return The sort order. + */ + @Override + public int compareTo(Completion c2) { + + int rc = -1; + + if (c2==this) { + rc = 0; + } + + else if (c2 instanceof MethodCompletion) { + rc = getCompareString().compareTo( + ((MethodCompletion)c2).getCompareString()); + } + + else if (c2!=null) { + rc = toString().compareToIgnoreCase(c2.toString()); + if (rc==0) { // Same text value + String clazz1 = getClass().getName(); + clazz1 = clazz1.substring(clazz1.lastIndexOf('.')); + String clazz2 = c2.getClass().getName(); + clazz2 = clazz2.substring(clazz2.lastIndexOf('.')); + rc = clazz1.compareTo(clazz2); + } + } + + return rc; + + } + + + @Override + public boolean equals(Object obj) { + return (obj instanceof MethodCompletion) && + //((MethodCompletion)obj).getSignature().equals(getSignature()); + ((MethodCompletion)obj).getCompareString().equals(getCompareString()); + } + + + @Override + public String getAlreadyEntered(JTextComponent comp) { + String temp = getProvider().getAlreadyEnteredText(comp); + int lastDot = temp.lastIndexOf('.'); + if (lastDot>-1) { + temp = temp.substring(lastDot+1); + } + return temp; + } + + + /** + * Returns a string used to compare this method completion to another. + * + * @return The comparison string. + */ + private String getCompareString() { + + /* + * This string compares the following parts of methods in this order, + * to optimize sort order in completion lists. + * + * 1. First, by name + * 2. Next, by number of parameters. + * 3. Finally, by parameter type. + */ + + if (compareString==null) { + StringBuilder sb = new StringBuilder(getName()); + // NOTE: This will fail if a method has > 99 parameters (!) + int paramCount = getParamCount(); + if (paramCount<10) { + sb.append('0'); + } + sb.append(paramCount); + for (int i=0; i-1) { + shortType = shortType.substring(dot+1); + } + + // Draw the method signature + String sig = mc.getSignature(); + FontMetrics fm = g.getFontMetrics(); + g.drawString(sig, x, y); + int newX = x + fm.stringWidth(sig); + if (mc.isDeprecated()) { + int midY = y + fm.getDescent() - fm.getHeight()/2; + g.drawLine(x, midY, newX, midY); + } + x = newX; + + // Append the return type + StringBuilder sb = new StringBuilder(" : ").append(shortType); + sb.append(" - "); + String s = sb.toString(); + g.drawString(s, x, y); + x += fm.stringWidth(s); + + // Append the type of the containing class of this member. + Color origColor = g.getColor(); + if (!selected) { + g.setColor(Color.GRAY); + } + g.drawString(mc.getEnclosingClassName(false), x, y); + if (!selected) { + g.setColor(origColor); + } + + } + + + /** + * {@inheritDoc} + */ + @Override + public String toString() { + return getSignature(); + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/MethodData.java b/src/main/java/org/fife/rsta/ac/bsh/MethodData.java new file mode 100644 index 00000000..0e48824c --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/MethodData.java @@ -0,0 +1,121 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh; + +import org.fife.rsta.ac.bsh.MemberCompletion.Data; +import org.fife.rsta.ac.bsh.rjc.ast.Method; +import org.fife.rsta.ac.bsh.rjc.ast.TypeDeclaration; +import org.fife.rsta.ac.bsh.rjc.lang.Modifiers; +import org.fife.rsta.ac.bsh.rjc.lang.Type; + + +/** + * Metadata about a method as read from a Java source file. This class is + * used by instances of {@link MethodCompletion}. + * + * @author Robert Futrell + * @version 1.0 + */ +class MethodData implements Data { + + private Method method; + + + public MethodData(Method method) { + this.method = method; + } + + + /** + * {@inheritDoc} + */ + public String getEnclosingClassName(boolean fullyQualified) { + // NOTE: This check isn't really necessary, but is here just in case + // there's a bug in the parsing code. + TypeDeclaration td = method.getParentTypeDeclaration(); + if (td==null) { + new Exception("No parent type declaration for: " + getSignature()). + printStackTrace(); + return ""; + } + return td.getName(fullyQualified); + } + + + public String getIcon() { + + String key = null; + + Modifiers mod = method.getModifiers(); + if (mod==null) { + key = IconFactory.METHOD_DEFAULT_ICON; + } + else if (mod.isPrivate()) { + key = IconFactory.METHOD_PRIVATE_ICON; + } + else if (mod.isProtected()) { + key = IconFactory.METHOD_PROTECTED_ICON; + } + else if (mod.isPublic()) { + key = IconFactory.METHOD_PUBLIC_ICON; + } + else { + key = IconFactory.METHOD_DEFAULT_ICON; + } + + return key; + + } + + + public String getSignature() { + return method.getNameAndParameters(); + } + + + public String getSummary() { + String docComment = method.getDocComment(); + return docComment!=null ? docComment : method.toString(); + } + + + public String getType() { + Type type = method.getType(); + return type==null ? "void" : type.toString(); + } + + + public boolean isAbstract() { + return method.getModifiers().isAbstract(); + } + + + public boolean isConstructor() { + return method.isConstructor(); + } + + + public boolean isDeprecated() { + return method.isDeprecated(); + } + + + public boolean isFinal() { + return method.getModifiers().isFinal(); + } + + + public boolean isStatic() { + return method.getModifiers().isStatic(); + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/MethodInfoData.java b/src/main/java/org/fife/rsta/ac/bsh/MethodInfoData.java new file mode 100644 index 00000000..68a3130c --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/MethodInfoData.java @@ -0,0 +1,371 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.fife.rsta.ac.bsh.MemberCompletion.Data; +import org.fife.rsta.ac.bsh.buildpath.SourceLocation; +import org.fife.rsta.ac.bsh.classreader.ClassFile; +import org.fife.rsta.ac.bsh.classreader.MethodInfo; +import org.fife.rsta.ac.bsh.classreader.Util; +import org.fife.rsta.ac.bsh.rjc.ast.CompilationUnit; +import org.fife.rsta.ac.bsh.rjc.ast.FormalParameter; +import org.fife.rsta.ac.bsh.rjc.ast.Member; +import org.fife.rsta.ac.bsh.rjc.ast.Method; +import org.fife.rsta.ac.bsh.rjc.ast.TypeDeclaration; + + +/** + * Metadata about a method as read from a class file. This class is used by + * instances of {@link MethodCompletion}. + * + * @author Robert Futrell + * @version 1.0 + */ +class MethodInfoData implements Data { + + /** + * The parent completion provider. + */ + private SourceCompletionProvider provider; + + /** + * The actual metadata. + */ + private MethodInfo info; + + /** + * Cached method parameter names. + */ + private List paramNames; + + + /** + * Constructor. + * + * @param info + * @param provider + */ + public MethodInfoData(MethodInfo info, SourceCompletionProvider provider) { + this.info = info; + this.provider = provider; + } + + + /** + * {@inheritDoc} + */ + public String getEnclosingClassName(boolean fullyQualified) { + return info.getClassFile().getClassName(fullyQualified); + } + + + /** + * {@inheritDoc} + */ + public String getIcon() { + + String key = null; + int flags = info.getAccessFlags(); + + if (Util.isDefault(flags)) { + key = IconFactory.METHOD_DEFAULT_ICON; + } + else if (Util.isPrivate(flags)) { + key = IconFactory.METHOD_PRIVATE_ICON; + } + else if (Util.isProtected(flags)) { + key = IconFactory.METHOD_PROTECTED_ICON; + } + else if (Util.isPublic(flags)) { + key = IconFactory.METHOD_PUBLIC_ICON; + } + else { + key = IconFactory.METHOD_DEFAULT_ICON; + } + + return key; + + } + + + /** + * Scours the source in a location (zip file, directory), looking for a + * particular class's source. If it is found, it is parsed, and the + * {@link Method} for this method (if any) is returned. + * + * @param loc The zip file, jar file, or directory to look in. + * @param cf The {@link ClassFile} representing the class of this method. + * @return The method, or null if it cannot be found, or an + * IO error occurred. + */ + private Method getMethodFromSourceLoc(SourceLocation loc, ClassFile cf) { + + Method res = null; + CompilationUnit cu = org.fife.rsta.ac.bsh.Util. + getCompilationUnitFromDisk(loc, cf); + + // If the class's source was found and successfully parsed, look for + // this method. + if (cu!=null) { + + Iterator i = cu.getTypeDeclarationIterator(); + while (i.hasNext()) { + + TypeDeclaration td = i.next(); + String typeName = td.getName(); + + // Avoid inner classes, etc. + if (typeName.equals(cf.getClassName(false))) { + + // Get all overloads of this method with the number of + // parameters we're looking for. 99% of the time, there + // will only be 1, the method we're looking for. + List contenders = null; + for (int j=0; j(1); // Usually just 1 + } + contenders.add(m2); + } + } + } + + // We found some matches. + if (contenders!=null) { + + // Common case - only 1 overload with the desired + // number of parameters => it must be our method. + if (contenders.size()==1) { + res = contenders.get(0); + } + + // More than 1 overload with the same number of + // parameters... we decide which contender is the one + // we're looking for by checking each of its + // parameters' types and making sure they're correct. + else { + for (Method method : contenders) { + boolean match = true; + for (int p=0; pnull if it cannot be determined. + * + * @param index The index of the parameter. + * @return The name of the parameter, or null. + */ + public String getParameterName(int index) { + + // First, check whether the debugging attribute was enabled at + // compilation, and the parameter name is embedded in the class file. + // This method takes priority because it *likely* matches a name + // specified in Javadoc, and is much faster for us to fetch (it's + // already parsed). + String name = info.getParameterName(index); + + // Otherwise... + if (name==null) { + + // Next, check the attached source, if any (lazily parsed). + if (paramNames==null) { + + paramNames = new ArrayList(1); + int offs = 0; + String rawSummary = getSummary(); + + // If there's attached source with Javadoc for this method... + if (rawSummary!=null && rawSummary.startsWith("/**")) { + + int nextParam = 0; + int summaryLen = rawSummary.length(); + + while ((nextParam=rawSummary.indexOf("@param", offs))>-1) { + int temp = nextParam + "@param".length() + 1; + while (tempnull if the method has no javadoc, + * the class's source was not found, or an IO error occurred. + */ + private String getSummaryFromSourceLoc(SourceLocation loc, ClassFile cf) { + Method method = getMethodFromSourceLoc(loc, cf); + return method!=null ? method.getDocComment() : null; + } + + + /** + * {@inheritDoc} + */ + public String getType() { + return info.getReturnTypeString(false); + } + + + public boolean isAbstract() { + return info.isAbstract(); + } + + + /** + * {@inheritDoc} + */ + public boolean isConstructor() { + return info.isConstructor(); + } + + + /** + * {@inheritDoc} + */ + public boolean isDeprecated() { + return info.isDeprecated(); + } + + + public boolean isFinal() { + return info.isFinal(); + } + + + public boolean isStatic() { + return info.isStatic(); + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/PackageMapNode.java b/src/main/java/org/fife/rsta/ac/bsh/PackageMapNode.java new file mode 100644 index 00000000..f74ba8fd --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/PackageMapNode.java @@ -0,0 +1,385 @@ +/* + * 04/04/2015 + * + * Copyright (C) 2015 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh; + +import java.io.IOException; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.SortedMap; +import java.util.TreeMap; + +import org.fife.rsta.ac.bsh.buildpath.LibraryInfo; +import org.fife.rsta.ac.bsh.classreader.ClassFile; +import org.fife.ui.autocomplete.Completion; +import org.fife.ui.autocomplete.CompletionProvider; + + +/** + * A data structure modeling all classes in a jar or directory, or on a + * classpath. It's a recursive mapping of Strings to either + * Maps or {@link ClassFile}s (which are lazily created and + * may be null). At each level of the nested map, the string + * key is a package name iff its corresponding value is a Map. + * Examine that Map's contents to explore the contents of + * that package. If the corresponding value is a ClassFile, + * then the string key's value is the name of that class. Finally, if + * the corresponding value is null, then the string key's + * value is the name of a class, but its contents have not yet been + * loaded for use by the code completion library (ClassFiles + * are lazily loaded to conserve memory). + */ +public class PackageMapNode { + + /** + * A mapping of sub-package name to the sub-packages and classes under it. + */ + private SortedMap subpackages; + + /** + * A mapping of class file names to class files in this package. The + * actual {@link ClassFile} values are lazily instantiated, so any map + * entry with a value of null simply has not been created + * yet. + */ + private SortedMap classFiles; + + + public PackageMapNode() { + subpackages = + new TreeMap(String.CASE_INSENSITIVE_ORDER); + classFiles = + new TreeMap(String.CASE_INSENSITIVE_ORDER); + } + + + /** + * Adds entries for a fully-qualified class name, of the form + * "org/fife/util/DynamicIntArray.class". This method should + * only be called on the "root" node of a package map. + * + * @param className A fully-qualified class name of the form described + * above. + */ + public void add(String className) { + + String[] tokens = Util.splitOnChar(className, '/'); + PackageMapNode pmn = this; + + for (int i=0; i.' character. This should be (the start of) a + * fully-qualified class, interface, or enum name. + * @param addTo The list to add completion choices to. + */ + public void addCompletions(LibraryInfo info, CompletionProvider provider, + String[] pkgNames, Set addTo) { + + PackageMapNode map = this; + for (int i=0; i largest valid class char + + // First add completions for matching subpackage names. + SortedMap subpackages = map.subpackages.subMap(fromKey, toKey); + if (!subpackages.isEmpty()) { + + StringBuilder sb = new StringBuilder(); + for (int j=0; j entry : subpackages.entrySet()) { + String completionPackageName = entry.getKey(); + String text = earlierPackages + completionPackageName; + addTo.add(new PackageNameCompletion(provider, text, fromKey)); + } + + } + + // Next, add completions for matching class names + SortedMap sm = map.classFiles.subMap(fromKey, toKey); + for (Map.Entry entry : sm.entrySet()) { + + String key = entry.getKey(); + ClassFile cf = entry.getValue(); + + // The ClassFile may have already been loaded for this one + if (cf != null) { + boolean inPkg = false; // TODO: Pass me in + if (inPkg || org.fife.rsta.ac.bsh.classreader.Util.isPublic(cf.getAccessFlags())) { + addTo.add(new ClassCompletion(provider, cf)); + } + } + + // If the ClassFile isn't yet cached + else { + String[] items = new String[pkgNames.length]; + System.arraycopy(pkgNames, 0, items, 0, pkgNames.length-1); + items[items.length-1] = key; + cf = getClassEntry(info, items); + if (cf!=null) { + boolean inPkg = false; // TODO: Pass me in + if (inPkg || org.fife.rsta.ac.bsh.classreader.Util.isPublic(cf.getAccessFlags())) { + addTo.add(new ClassCompletion(provider, cf)); + } + } + else { + // This should never happen - class name without a ClassFile + } + } + + } + + } + + + /** + * Removes the cache of all ClassFiles from this package + * map. + * + * @return The number of class file entries removed. + */ + public int clearClassFiles() { + return clearClassFilesImpl(this); + } + + + private int clearClassFilesImpl(PackageMapNode pmn) { + + int clearedCount = 0; + + for (Map.Entry entry : pmn.classFiles.entrySet()) { + entry.setValue(null); + clearedCount++; + } + + for (Map.Entry entry : pmn.subpackages.entrySet()) { + clearedCount += clearClassFilesImpl(entry.getValue()); + } + + return clearedCount; + + } + + + public boolean containsClass(String className) { + + String[] items = className.split("\\."); + + PackageMapNode pmn = this; + for (int i=0; i addTo, + String[] pkgs, boolean inPkg) { + + PackageMapNode map = this; + + for (int i=0; i entry : map.classFiles.entrySet()) { + + ClassFile cf = entry.getValue(); + if (cf == null) { + StringBuilder name = new StringBuilder(pkgs[0]); + for (int j=1; jmap belongs to (i.e. + * all levels of packages scanned before this one), separated by + * '/'. + * @param addTo The list to add any matching ClassFiles to. + */ + void getClassesWithNamesStartingWith(LibraryInfo info, String prefix, + String currentPkg, List addTo) { + + final int prefixLen = prefix.length(); + + for (Map.Entry children : subpackages.entrySet()) { + String key = children.getKey(); + PackageMapNode child = children.getValue(); + child.getClassesWithNamesStartingWith(info, prefix, + currentPkg + key + "/", addTo); + } + + for (Map.Entry cfEntry : classFiles.entrySet()) { + // If value is null, we only lazily create the ClassFile if + // necessary (i.e. if the class name does match what they've + // typed). + String className = cfEntry.getKey(); + if (className.regionMatches(true, 0, prefix, 0, prefixLen)) { + ClassFile cf = cfEntry.getValue(); + if (cf==null) { + String fqClassName = currentPkg + className + ".class"; + try { + cf = info.createClassFile(fqClassName); + cfEntry.setValue(cf); // Update the map + } catch (IOException ioe) { + ioe.printStackTrace(); + } + } + if (cf!=null) { // possibly null if IOException above + addTo.add(cf); + } + } + } + + } + + + private static final void possiblyAddTo(Collection addTo, + ClassFile cf, boolean inPkg) { + if (inPkg || org.fife.rsta.ac.bsh.classreader.Util.isPublic(cf.getAccessFlags())) { + addTo.add(cf); + } + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/PackageNameCompletion.java b/src/main/java/org/fife/rsta/ac/bsh/PackageNameCompletion.java new file mode 100644 index 00000000..8cdfa52a --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/PackageNameCompletion.java @@ -0,0 +1,58 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh; + +import java.awt.Graphics; +import javax.swing.Icon; + +import org.fife.ui.autocomplete.CompletionProvider; + + +/** + * A completion that represents a package name. + * + * @author Robert Futrell + * @version 1.0 + */ +class PackageNameCompletion extends AbstractJavaSourceCompletion { + + + public PackageNameCompletion(CompletionProvider provider, String text, + String alreadyEntered) { + super(provider, text.substring(text.lastIndexOf('.')+1)); + } + + + @Override + public boolean equals(Object obj) { + return (obj instanceof PackageNameCompletion) && + ((PackageNameCompletion)obj).getReplacementText().equals(getReplacementText()); + } + + + @Override + public Icon getIcon() { + return IconFactory.get().getIcon(IconFactory.PACKAGE_ICON); + } + + + @Override + public int hashCode() { + return getReplacementText().hashCode(); + } + + + public void rendererText(Graphics g, int x, int y, boolean selected) { + g.drawString(getInputText(), x, y); + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/SourceCompletionProvider.java b/src/main/java/org/fife/rsta/ac/bsh/SourceCompletionProvider.java new file mode 100644 index 00000000..4a4487b6 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/SourceCompletionProvider.java @@ -0,0 +1,1072 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh; + +import java.awt.Cursor; +import java.awt.Point; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; +import javax.swing.text.BadLocationException; +import javax.swing.text.JTextComponent; + +import org.fife.rsta.ac.ShorthandCompletionCache; +import org.fife.rsta.ac.bsh.buildpath.LibraryInfo; +import org.fife.rsta.ac.bsh.buildpath.SourceLocation; +import org.fife.rsta.ac.bsh.classreader.ClassFile; +import org.fife.rsta.ac.bsh.classreader.FieldInfo; +import org.fife.rsta.ac.bsh.classreader.MemberInfo; +import org.fife.rsta.ac.bsh.classreader.MethodInfo; +import org.fife.rsta.ac.bsh.rjc.ast.CodeBlock; +import org.fife.rsta.ac.bsh.rjc.ast.CompilationUnit; +import org.fife.rsta.ac.bsh.rjc.ast.Field; +import org.fife.rsta.ac.bsh.rjc.ast.FormalParameter; +import org.fife.rsta.ac.bsh.rjc.ast.ImportDeclaration; +import org.fife.rsta.ac.bsh.rjc.ast.LocalVariable; +import org.fife.rsta.ac.bsh.rjc.ast.Member; +import org.fife.rsta.ac.bsh.rjc.ast.Method; +import org.fife.rsta.ac.bsh.rjc.ast.NormalClassDeclaration; +import org.fife.rsta.ac.bsh.rjc.ast.TypeDeclaration; +import org.fife.rsta.ac.bsh.rjc.lang.Type; +import org.fife.rsta.ac.bsh.rjc.lang.TypeArgument; +import org.fife.rsta.ac.bsh.rjc.lang.TypeParameter; +import org.fife.ui.autocomplete.Completion; +import org.fife.ui.autocomplete.DefaultCompletionProvider; +import org.fife.ui.rsyntaxtextarea.RSyntaxDocument; +import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; +import org.fife.ui.rsyntaxtextarea.RSyntaxUtilities; +import org.fife.ui.rsyntaxtextarea.Token; + + +/** + * Parses a Java AST for code completions. It currently scans the following: + * + *
    + *
  • Import statements + *
  • Method names + *
  • Field names + *
+ * + * Also, if the caret is inside a method, local variables up to the caret + * position are also returned. + * + * @author Robert Futrell + * @version 1.0 + */ +class SourceCompletionProvider extends DefaultCompletionProvider { + + /** + * The parent completion provider. + */ + private JavaCompletionProvider javaProvider; + + /** + * Used to get information about what classes match imports. + */ + private JarManager jarManager; + + private static final String JAVA_LANG_PACKAGE = "java.lang.*"; + private static final String THIS = "this"; + + //Shorthand completions (templates and comments) + private ShorthandCompletionCache shorthandCache; + /** + * Constructor. + */ + public SourceCompletionProvider() { + this(null); + } + + + /** + * Constructor. + * + * @param jarManager The jar manager for this provider. + */ + public SourceCompletionProvider(JarManager jarManager) { + if (jarManager==null) { + jarManager = new JarManager(); + } + this.jarManager = jarManager; + setParameterizedCompletionParams('(', ", ", ')'); + setAutoActivationRules(false, "."); // Default - only activate after '.' + setParameterChoicesProvider(new SourceParamChoicesProvider()); + } + + + private void addCompletionsForStaticMembers(Set set, + CompilationUnit cu, ClassFile cf, String pkg) { + + // Check us first, so if we override anything, we get the "newest" + // version. + int methodCount = cf.getMethodCount(); + for (int i=0; i set, + CompilationUnit cu, ClassFile cf, String pkg, + Map typeParamMap) { + + // Reset this class's type-arguments-to-type-parameters map, so that + // when methods and fields need to know type arguments, they can query + // for them. + cf.setTypeParamsToTypeArgs(typeParamMap); + + // Check us first, so if we override anything, we get the "newest" + // version. + int methodCount = cf.getMethodCount(); + for (int i=0; i retVal) { + + Type type = var.getType(); + String pkg = cu.getPackageName(); + + if (type.isArray()) { + ClassFile cf = getClassFileFor(cu, "java.lang.Object"); + addCompletionsForExtendedClass(retVal, cu, cf, pkg, null); + FieldCompletion fc = FieldCompletion. + createLengthCompletion(this, type); + retVal.add(fc); + } + + else if (!type.isBasicType()) { + String typeStr = type.getName(true, false); + ClassFile cf = getClassFileFor(cu, typeStr); + if (cf!=null) { + Map typeParamMap = createTypeParamMap(type, cf); + addCompletionsForExtendedClass(retVal, cu, cf, pkg, typeParamMap); + } + } + + } + + + /** + * Adds simple shorthand completions relevant to Java. + * + * @param set The set to add to. + */ + private void addShorthandCompletions(Set set) { + if(shorthandCache != null) { + set.addAll(shorthandCache.getShorthandCompletions()); + } + } + + /** + * Set template completion cache for source completion provider. + * + * @param shorthandCache The new cache. + */ + public void setShorthandCache(ShorthandCompletionCache shorthandCache) { + this.shorthandCache = shorthandCache; + } + + + /** + * Gets the {@link ClassFile} for a class. + * + * @param cu The compilation unit being parsed. + * @param className The name of the class (fully qualified or not). + * @return The {@link ClassFile} for the class, or null if + * cf represents java.lang.Object (or + * if the super class could not be determined). + */ + private ClassFile getClassFileFor(CompilationUnit cu, String className) { + + //System.err.println(">>> Getting class file for: " + className); + if (className==null) { + return null; + } + + ClassFile superClass = null; + + // Determine the fully qualified class to grab + if (!Util.isFullyQualified(className)) { + + // Check in this source file's package first + String pkg = cu.getPackageName(); + if (pkg!=null) { + String temp = pkg + "." + className; + superClass = jarManager.getClassEntry(temp); + } + + // Next, go through the imports (order is important) + if (superClass==null) { + Iterator i = cu.getImportIterator(); + while (i.hasNext()) { + ImportDeclaration id = i.next(); + String imported = id.getName(); + if (imported.endsWith(".*")) { + String temp = imported.substring( + 0, imported.length()-1) + className; + superClass = jarManager.getClassEntry(temp); + if (superClass!=null) { + break; + } + } + else if (imported.endsWith("." + className)) { + superClass = jarManager.getClassEntry(imported); + break; + } + } + } + + // Finally, try java.lang + if (superClass==null) { + String temp = "java.lang." + className; + superClass = jarManager.getClassEntry(temp); + } + + } + + else { + superClass = jarManager.getClassEntry(className); + } + + return superClass; + + } + + + /** + * Adds completions for local variables in a method. + * + * @param set + * @param method + * @param offs The caret's offset into the source. This should be inside + * of method. + */ + private void addLocalVarCompletions(Set set, Method method, + int offs) { + + for (int i=0; iblock. + */ + private void addLocalVarCompletions(Set set, CodeBlock block, + int offs) { + + for (int i=0; ioffs) { + break; + } + } + + } + + + /** + * Adds a jar to read from. + * + * @param info The jar to add. If this is null, then + * the current JVM's main JRE jar (rt.jar, or classes.jar on OS X) + * will be added. If this jar has already been added, adding it + * again will do nothing (except possibly update its attached source + * location). + * @throws IOException If an IO error occurs. + * @see #getJars() + * @see #removeJar(File) + */ + public void addJar(LibraryInfo info) throws IOException { + jarManager.addClassFileSource(info); + } + + + /** + * Checks whether the user is typing a completion for a String member after + * a String literal. + * + * @param comp The text component. + * @param alreadyEntered The text already entered. + * @param cu The compilation unit being parsed. + * @param set The set to add possible completions to. + * @return Whether the user is indeed typing a completion for a String + * literal member. + */ + private boolean checkStringLiteralMember(JTextComponent comp, + String alreadyEntered, + CompilationUnit cu, Set set) { + + boolean stringLiteralMember = false; + + int offs = comp.getCaretPosition() - alreadyEntered.length() - 1; + if (offs>1) { + RSyntaxTextArea textArea = (RSyntaxTextArea)comp; + RSyntaxDocument doc = (RSyntaxDocument)textArea.getDocument(); + try { + //System.out.println(doc.charAt(offs) + ", " + doc.charAt(offs+1)); + if (doc.charAt(offs)=='"' && doc.charAt(offs+1)=='.') { + int curLine = textArea.getLineOfOffset(offs); + Token list = textArea.getTokenListForLine(curLine); + Token prevToken = RSyntaxUtilities.getTokenAtOffset(list, offs); + if (prevToken!=null && + prevToken.getType()==Token.LITERAL_STRING_DOUBLE_QUOTE) { + ClassFile cf = getClassFileFor(cu, "java.lang.String"); + addCompletionsForExtendedClass(set, cu, cf, + cu.getPackageName(), null); + stringLiteralMember = true; + } + else { + System.out.println(prevToken); + } + } + } catch (BadLocationException ble) { // Never happens + ble.printStackTrace(); + } + } + + return stringLiteralMember; + + } + + + /** + * Removes all jars from the "build path." + * + * @see #removeJar(File) + * @see #addJar(LibraryInfo) + * @see #getJars() + */ + public void clearJars() { + jarManager.clearClassFileSources(); + // The memory used by the completions can be quite large, so go ahead + // and clear out the completions list so no-longer-needed ones are + // eligible for GC. + clear(); + } + + + /** + * Creates and returns a mapping of type parameters to type arguments. + * + * @param type The type of a variable/field/etc. whose fields/methods/etc. + * are being code completed, as declared in the source. This + * includes type arguments. + * @param cf The ClassFile representing the actual type of + * the variable/field/etc. being code completed + * @return A mapping of type parameter names to type arguments (both + * Strings). + */ + private Map createTypeParamMap(Type type, ClassFile cf) { + Map typeParamMap = null; + List typeArgs = type.getTypeArguments(type.getIdentifierCount()-1); + if (typeArgs!=null) { + typeParamMap = new HashMap(); + List paramTypes = cf.getParamTypes(); + // Should be the same size! Otherwise, the source code has + // too many/too few type arguments listed for this type. + int min = Math.min(paramTypes==null ? 0 : paramTypes.size(), + typeArgs.size()); + for (int i=0; i getCompletionsAt(JTextComponent tc, Point p) { + getCompletionsImpl(tc); // Force loading of completions + return super.getCompletionsAt(tc, p); + } + + + /** + * {@inheritDoc} + */ + @Override + protected List getCompletionsImpl(JTextComponent comp) { + + comp.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + + try { + + completions = new ArrayList();//completions.clear(); + + CompilationUnit cu = javaProvider.getCompilationUnit(); + if (cu==null) { + return completions; // empty + } + + Set set = new TreeSet(); + + // Cut down the list to just those matching what we've typed. + // Note: getAlreadyEnteredText() never returns null + String text = getAlreadyEnteredText(comp); + + // Special case - end of a String literal + boolean stringLiteralMember = checkStringLiteralMember(comp, text, cu, + set); + + // Not after a String literal - regular code completion + if (!stringLiteralMember) { + + // Don't add shorthand completions if they're typing something + // qualified + if (text.indexOf('.')==-1) { + addShorthandCompletions(set); + } + + loadImportCompletions(set, text, cu); + + // Add completions for fully-qualified stuff (e.g. "com.sun.jav") + //long startTime = System.currentTimeMillis(); + jarManager.addCompletions(this, text, set); + //long time = System.currentTimeMillis() - startTime; + //System.out.println("jar completions loaded in: " + time); + + // Loop through all types declared in this source, and provide + // completions depending on in what type/method/etc. the caret's in. + loadCompletionsForCaretPosition(cu, comp, text, set); + + } + + // Do a final sort of all of our completions and we're good to go! + completions = new ArrayList(set); + Collections.sort(completions); + + // Only match based on stuff after the final '.', since that's what is + // displayed for all of our completions. + text = text.substring(text.lastIndexOf('.')+1); + + @SuppressWarnings("unchecked") + int start = Collections.binarySearch(completions, text, comparator); + if (start<0) { + start = -(start+1); + } + else { + // There might be multiple entries with the same input text. + while (start>0 && + comparator.compare(completions.get(start-1), text)==0) { + start--; + } + } + + @SuppressWarnings("unchecked") + int end = Collections.binarySearch(completions, text+'{', comparator); + end = -(end+1); + + return completions.subList(start, end); + + } finally { + comp.setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR)); + } + + } + + + /** + * Returns the jars on the "build path." + * + * @return A list of {@link LibraryInfo}s. Modifying a + * LibraryInfo in this list will have no effect on + * this completion provider; in order to do that, you must re-add + * the jar via {@link #addJar(LibraryInfo)}. If there are + * no jars on the "build path," this will be an empty list. + * @see #addJar(LibraryInfo) + */ + public List getJars() { + return jarManager.getClassFileSources(); + } + + + +public SourceLocation getSourceLocForClass(String className) { + return jarManager.getSourceLocForClass(className); +} + + /** + * Returns whether a method defined by a super class is accessible to + * this class. + * + * @param info Information about the member. + * @param pkg The package of the source currently being parsed. + * @return Whether or not the method is accessible. + */ + private boolean isAccessible(MemberInfo info, String pkg) { + + boolean accessible = false; + int access = info.getAccessFlags(); + + if (org.fife.rsta.ac.bsh.classreader.Util.isPublic(access) || + org.fife.rsta.ac.bsh.classreader.Util.isProtected(access)) { + accessible = true; + } + else if (org.fife.rsta.ac.bsh.classreader.Util.isDefault(access)) { + String pkg2 = info.getClassFile().getPackageName(); + accessible = (pkg==null && pkg2==null) || + (pkg!=null && pkg.equals(pkg2)); + } + + return accessible; + + } + + + /** + * {@inheritDoc} + */ + @Override + protected boolean isValidChar(char ch) { + return Character.isJavaIdentifierPart(ch) || ch=='.'; + } + + + /** + * Loads completions based on the current caret location in the source. In + * other words: + * + *
    + *
  • If the caret is anywhere in a class, the names of all methods and + * fields in the class are loaded. Methods and fields in super + * classes are also loaded. TODO: Get super methods/fields added + * correctly by access! + *
  • If the caret is in a field, local variables currently accessible + * are loaded. + *
+ * + * @param cu + * @param comp + * @param alreadyEntered + * @param retVal + */ + private void loadCompletionsForCaretPosition(CompilationUnit cu, + JTextComponent comp, String alreadyEntered, Set retVal) { + + // Get completions for all fields and methods of all type declarations. + + //long startTime = System.currentTimeMillis(); + int caret = comp.getCaretPosition(); + //List temp = new ArrayList(); + int start, end; + + int lastDot = alreadyEntered.lastIndexOf('.'); + boolean qualified = lastDot>-1; + String prefix = qualified ? alreadyEntered.substring(0, lastDot) : null; + + Iterator i = cu.getTypeDeclarationIterator(); + while (i.hasNext()) { + + TypeDeclaration td = i.next(); + start = td.getBodyStartOffset(); + end = td.getBodyEndOffset(); + + if (caret>start && caret<=end) { + loadCompletionsForCaretPosition(cu, comp, alreadyEntered, + retVal, td, prefix, caret); + } + + else if (caret + *
  • If the caret is anywhere in a class, the names of all methods and + * fields in the class are loaded. Methods and fields in super + * classes are also loaded. TODO: Get super methods/fields added + * correctly by access! + *
  • If the caret is in a field, local variables currently accessible + * are loaded. + * + * + * @param cu + * @param comp + * @param alreadyEntered + * @param retVal + */ + private void loadCompletionsForCaretPosition(CompilationUnit cu, + JTextComponent comp, String alreadyEntered, Set retVal, + TypeDeclaration td, String prefix, int caret) { + + // Do any child types first, so if any vars, etc. have duplicate names, + // we pick up the one "closest" to us first. + for (int i=0; i typeParamMap = new HashMap(); + if (td instanceof NormalClassDeclaration) { + NormalClassDeclaration ncd = (NormalClassDeclaration)td; + List typeParams = ncd.getTypeParameters(); + if (typeParams!=null) { + for (TypeParameter typeParam : typeParams) { + String typeVar = typeParam.getName(); + // For non-qualified completions, use type var name. + typeParamMap.put(typeVar, typeVar); + } + } + } + + // Get completions for this class's methods, fields and local + // vars. Do this before checking super classes so that, if + // we overrode anything, we get the "newest" version. + String pkg = cu.getPackageName(); + Iterator j = td.getMemberIterator(); + while (j.hasNext()) { + Member m = j.next(); + if (m instanceof Method) { + Method method = (Method)m; + if (prefix==null || THIS.equals(prefix)) { + retVal.add(new MethodCompletion(this, method)); + } + if (caret>=method.getBodyStartOffset() && caretnull if + * none. + * @param prefix The text up to the current caret position. This is + * guaranteed to be non-null not equal to + * "this". + * @param offs The offset of the caret in the document. + */ + private void loadCompletionsForCaretPositionQualified(CompilationUnit cu, + String alreadyEntered, Set retVal, + TypeDeclaration td, Method currentMethod, String prefix, int offs) { + + // TODO: Remove this restriction. + int dot = prefix.indexOf('.'); + if (dot>-1) { + System.out.println("[DEBUG]: Qualified non-this completions currently only go 1 level deep"); + return; + } + + // TODO: Remove this restriction. + else if (!prefix.matches("[A-Za-z_][A-Za-z0-9_\\$]*")) { + System.out.println("[DEBUG]: Only identifier non-this completions are currently supported"); + return; + } + + String pkg = cu.getPackageName(); + boolean matched = false; + + for (Iterator j=td.getMemberIterator(); j.hasNext(); ) { + + Member m = j.next(); + + // The prefix might be a field in the local class. + if (m instanceof Field) { + + Field field = (Field)m; + + if (field.getName().equals(prefix)) { + //System.out.println("FOUND: " + prefix + " (" + pkg + ")"); + Type type = field.getType(); + if (type.isArray()) { + ClassFile cf = getClassFileFor(cu, "java.lang.Object"); + addCompletionsForExtendedClass(retVal, cu, cf, pkg, null); + FieldCompletion fc = FieldCompletion. + createLengthCompletion(this, type); + retVal.add(fc); + } + else if (!type.isBasicType()) { + String typeStr = type.getName(true, false); + ClassFile cf = getClassFileFor(cu, typeStr); + // Add completions for extended class type chain + if (cf!=null) { + Map typeParamMap = createTypeParamMap(type, cf); + addCompletionsForExtendedClass(retVal, cu, cf, pkg, typeParamMap); + // Add completions for all implemented interfaces + // TODO: Only do this if type is abstract! + for (int i=0; i imports = cu.getImports(); + List matches = jarManager.getClassesWithUnqualifiedName( + prefix, imports); + if (matches!=null) { + for (int i=0; i retVal, + TypeDeclaration td, CodeBlock block, String prefix, int offs) { + + boolean found = false; + + for (int i=0; ioffs) { + break; + } + } + + } + + + /** + * Loads completions for a single import statement. + * + * @param importStr The import statement. + * @param pkgName The package of the source currently being parsed. + */ + private void loadCompletionsForImport(Set set, + String importStr, String pkgName) { + + if (importStr.endsWith(".*")) { + String pkg = importStr.substring(0, importStr.length()-2); + boolean inPkg = pkg.equals(pkgName); + List classes= jarManager.getClassesInPackage(pkg, inPkg); + for (ClassFile cf : classes) { + set.add(new ClassCompletion(this, cf)); + } + } + + else { + ClassFile cf = jarManager.getClassEntry(importStr); + if (cf!=null) { + set.add(new ClassCompletion(this, cf)); + } + } + + } + + + /** + * Loads completions for all import statements. + * + * @param cu The compilation unit being parsed. + */ + private void loadImportCompletions(Set set, String text, + CompilationUnit cu) { + + // Fully-qualified completions are handled elsewhere, so no need to + // duplicate the work here + if (text.indexOf('.')>-1) { + return; + } + + //long startTime = System.currentTimeMillis(); + + String pkgName = cu.getPackageName(); + loadCompletionsForImport(set, JAVA_LANG_PACKAGE, pkgName); + for (Iterator i=cu.getImportIterator(); i.hasNext(); ) { + ImportDeclaration id = i.next(); + String name = id.getName(); + if (!JAVA_LANG_PACKAGE.equals(name)) { + loadCompletionsForImport(set, name, pkgName); + } + } +// Collections.sort(completions); + + //long time = System.currentTimeMillis() - startTime; + //System.out.println("imports loaded in: " + time); + + } + + + /** + * Removes a jar from the "build path." + * + * @param jar The jar to remove. + * @return Whether the jar was removed. This will be false + * if the jar was not on the build path. + * @see #addJar(LibraryInfo) + * @see #getJars() + * @see #clearJars() + */ + public boolean removeJar(File jar) { + boolean removed = jarManager.removeClassFileSource(jar); + // The memory used by the completions can be quite large, so go ahead + // and clear out the completions list so no-longer-needed ones are + // eligible for GC. + if (removed) { + clear(); + } + return removed; + } + + + /** + * Sets the parent Java provider. + * + * @param javaProvider The parent completion provider. + */ + void setJavaProvider(JavaCompletionProvider javaProvider) { + this.javaProvider = javaProvider; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/SourceParamChoicesProvider.java b/src/main/java/org/fife/rsta/ac/bsh/SourceParamChoicesProvider.java new file mode 100644 index 00000000..0deb19f8 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/SourceParamChoicesProvider.java @@ -0,0 +1,337 @@ +/* + * 12/14/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh; + +import java.awt.Graphics; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import javax.swing.Icon; +import javax.swing.text.JTextComponent; + +import org.fife.rsta.ac.LanguageSupport; +import org.fife.rsta.ac.LanguageSupportFactory; +import org.fife.rsta.ac.bsh.rjc.ast.CodeBlock; +import org.fife.rsta.ac.bsh.rjc.ast.CompilationUnit; +import org.fife.rsta.ac.bsh.rjc.ast.Field; +import org.fife.rsta.ac.bsh.rjc.ast.FormalParameter; +import org.fife.rsta.ac.bsh.rjc.ast.LocalVariable; +import org.fife.rsta.ac.bsh.rjc.ast.Member; +import org.fife.rsta.ac.bsh.rjc.ast.Method; +import org.fife.rsta.ac.bsh.rjc.ast.NormalClassDeclaration; +import org.fife.rsta.ac.bsh.rjc.ast.NormalInterfaceDeclaration; +import org.fife.rsta.ac.bsh.rjc.ast.Package; +import org.fife.rsta.ac.bsh.rjc.ast.TypeDeclaration; +import org.fife.rsta.ac.bsh.rjc.lang.Type; +import org.fife.ui.autocomplete.BasicCompletion; +import org.fife.ui.autocomplete.Completion; +import org.fife.ui.autocomplete.CompletionProvider; +import org.fife.ui.autocomplete.EmptyIcon; +import org.fife.ui.autocomplete.ParameterChoicesProvider; +import org.fife.ui.autocomplete.ParameterizedCompletion; +import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; +import org.fife.ui.rsyntaxtextarea.modes.JavaTokenRegistration; + + +/** + * A parameter choices provider for Java methods.

    + * NOTE: This class is not thread-safe, but it's assumed that it is only + * ever called on the EDT, so it should be a non-issue. + * + * @author Robert Futrell + * @version 1.0 + */ +class SourceParamChoicesProvider implements ParameterChoicesProvider { + + /** + * The parent {@link JavaCompletionProvider}. + */ + private CompletionProvider provider; + + + /** + * Adds all accessible fields and getters of a specific type, from an + * extended class or implemented interface. + * + * @param type + * @param jm + * @param pkg + * @param list + */ + private void addPublicAndProtectedFieldsAndGetters(Type type, JarManager jm, + Package pkg, List list) { + + // TODO: Implement me. + + } + + + /** + * Gets all local variables, fields, and simple getters defined in a + * class, that are of a specific type, and are accessible from a given + * offset. + * + * @param ncd The class. + * @param type The type that the variables, fields, and (return value of) + * getters must be. + * @param offs The offset of the caret. + * @return The list of stuff, or an empty list if none are found. + */ + public List getLocalVarsFieldsAndGetters( + NormalClassDeclaration ncd, String type, int offs) { + + List members = new ArrayList(); + + if (!ncd.getBodyContainsOffset(offs)) { + return members; + } + + // First, if the offset is in a method, get any local variables in + // that method. + Method method = ncd.getMethodContainingOffset(offs); + if (method!=null) { + + // Parameters to the method + Iterator i = method.getParameterIterator(); + while (i.hasNext()) { + FormalParameter param = i.next(); + Type paramType = param.getType(); + if (isTypeCompatible(paramType, type)) { + //members.add(param.getName()); + members.add(new LocalVariableCompletion(provider, param)); + } + } + + // Local variables in the method + CodeBlock body = method.getBody(); + if (body!=null) { // Should always be true? + CodeBlock block = body.getDeepestCodeBlockContaining(offs); + List vars = block.getLocalVarsBefore(offs); + for (LocalVariable var : vars) { + Type varType = var.getType(); + if (isTypeCompatible(varType, type)) { + //members.add(var.getName()); + members.add(new LocalVariableCompletion(provider, var)); + } + } + } + + } + + // Next, any fields/getters taking no parameters (for simplicity) + // in this class. + for (Iterator i=ncd.getMemberIterator(); i.hasNext(); ) { + + Member member = i.next(); + + if (member instanceof Field) { + Type fieldType = member.getType(); + if (isTypeCompatible(fieldType, type)) { + //members.add(member.getName()); + members.add(new FieldCompletion(provider, (Field)member)); + } + } + else { // Method + method = (Method)member; + if (isSimpleGetter(method)) { + if (isTypeCompatible(method.getType(), type)) { + //members.add(member.getName() + "()"); + members.add(new MethodCompletion(provider, method)); + } + } + } + + } + + return members; + + } + + + /** + * {@inheritDoc} + */ + public List getParameterChoices(JTextComponent tc, + ParameterizedCompletion.Parameter param) { + + // Get the language support for Java + LanguageSupportFactory lsf = LanguageSupportFactory.get(); + LanguageSupport support = lsf.getSupportFor(JavaTokenRegistration.SYNTAX_STYLE); + JavaLanguageSupport jls = (JavaLanguageSupport)support; + JarManager jm = jls.getJarManager(); + + // Get the deepest TypeDeclaration AST containing the caret position + // for the source code in the editor. + RSyntaxTextArea textArea = (RSyntaxTextArea)tc; + JavaParser parser = jls.getParser(textArea); + if (parser==null) { + return null; + } + CompilationUnit cu = parser.getCompilationUnit(); + if (cu==null) { + return null; + } + int dot = tc.getCaretPosition(); + TypeDeclaration typeDec = cu.getDeepestTypeDeclarationAtOffset(dot); + if (typeDec==null) { + return null; + } + + List list = null; + Package pkg = typeDec.getPackage(); + provider = jls.getCompletionProvider(textArea); + + // If we're in a class, we'll have to check for local variables, etc. + if (typeDec instanceof NormalClassDeclaration) { + + // Get accessible members of this type. + NormalClassDeclaration ncd = (NormalClassDeclaration)typeDec; + list = getLocalVarsFieldsAndGetters(ncd, param.getType(), dot); +// list = typeDec.getAccessibleMembersOfType(param.getType(), dot); + + // Get accessible members of the extended type. + Type extended = ncd.getExtendedType(); + if (extended!=null) { + addPublicAndProtectedFieldsAndGetters(extended, jm, pkg, list); + } + + // Get accessible members of any implemented interfaces. + for (Iterator i=ncd.getImplementedIterator(); i.hasNext(); ) { + Type implemented = i.next(); + addPublicAndProtectedFieldsAndGetters(implemented,jm,pkg,list); + } + + + } + + // If we're an interface, local vars, etc. don't exist + else if (typeDec instanceof NormalInterfaceDeclaration) { + // Nothing to do + } + + // If we're in an enum... + else {//if (typeDec instanceof EnumDeclaration) { + // TODO: Implement me + } + + // Check for any public/protected fields/getters in enclosing type. + if (!typeDec.isStatic()) { + // TODO: Implement me. + } + + // Add defaults for common types - "0" for primitive numeric types, + // "null" for Objects, etc. + Object typeObj = param.getTypeObject(); + // TODO: Not all Parameters have typeObj set to a Type yet! Make me so + if (typeObj instanceof Type) { + Type type = (Type)typeObj; + if (type.isBasicType()) { + if (isPrimitiveNumericType(type)) { + list.add(new SimpleCompletion(provider, "0")); + } + else { // is a "boolean" type + list.add(new SimpleCompletion(provider, "false")); + list.add(new SimpleCompletion(provider, "true")); + } + } + else { + list.add(new SimpleCompletion(provider, "null")); + } + } + + // And we're done! + return list; + + } + + + private boolean isPrimitiveNumericType(Type type) { + String str = type.getName(true); + return "byte".equals(str) || "float".equals(str) || + "double".equals(str) || "int".equals(str) || + "short".equals(str) || "long".equals(str); + } + + + /** + * Returns whether a method is a no-argument getter method. + * + * @param method The method. + * @return Whether it is a no-argument getter. + */ + private boolean isSimpleGetter(Method method) { + return method.getParameterCount()==0 && + method.getName().startsWith("get"); + } + + + /** + * Returns whether a Type and a type name are type + * compatible. This method currently is a sham! + * + * @param type + * @param typeName + * @return + */ + // TODO: Get me working! Probably need better parameters passed in!!! + private boolean isTypeCompatible(Type type, String typeName) { + + String typeName2 = type.getName(false); + + // Remove generics info for now + // TODO: Handle messy generics cases + int lt = typeName2.indexOf('<'); + if (lt>-1) { + String arrayDepth = null; + int brackets = typeName2.indexOf('[', lt); + if (brackets>-1) { + arrayDepth = typeName2.substring(brackets); + } + typeName2 = typeName2.substring(lt); + if (arrayDepth!=null) { + typeName2 += arrayDepth; + } + } + + return typeName2.equalsIgnoreCase(typeName); + + } + + + /** + * A very simple, low-relevance parameter choice completion. This is + * never used as a general-purpose completion in Java code, as it cannot + * render itself. + */ + private static class SimpleCompletion extends BasicCompletion + implements JavaSourceCompletion { + + private Icon ICON = new EmptyIcon(16); + + public SimpleCompletion(CompletionProvider provider, String text) { + super(provider, text); + setRelevance(-1); + } + + @Override + public Icon getIcon() { + return ICON; + } + + public void rendererText(Graphics g, int x, int y, boolean selected) { + // Never called + } + + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/Util.java b/src/main/java/org/fife/rsta/ac/bsh/Util.java new file mode 100644 index 00000000..d6971660 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/Util.java @@ -0,0 +1,728 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.StringReader; +import java.text.CharacterIterator; +import java.text.StringCharacterIterator; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.fife.rsta.ac.bsh.buildpath.SourceLocation; +import org.fife.rsta.ac.bsh.classreader.ClassFile; +import org.fife.rsta.ac.bsh.rjc.ast.CompilationUnit; + + +/** + * Utility methods for Java completion. + * + * @author Robert Futrell + * @version 1.0 + */ +public class Util { + + /** + * Optional leading text for doc comment lines (except the first line) that + * should be removed if it exists. + */ + static final Pattern DOC_COMMENT_LINE_HEADER = + Pattern.compile("\\s*\\n\\s*\\*");//^\\s*\\*\\s*[/]?"); + + /** + * Pattern matching a link in a "@link" tag. This should + * match the following: + * + *

      + *
    • ClassName
    • + *
    • fully.qualified.ClassName
    • + *
    • #method
    • + *
    • #method(int, int)
    • + *
    • String#method
    • + *
    • String#method(params)
    • + *
    • fully.qualified.ClassName#method
    • + *
    • fully.qualified.ClassName#method(params)
    • + *
    + * + * Hyperlinks ("<a href=...") are not matched and should be + * handled separately. + */ + static final Pattern LINK_TAG_MEMBER_PATTERN = + Pattern.compile("(?:\\w+\\.)*\\w+(?:#\\w+(?:\\([^\\)]*\\))?)?|" + + "#\\w+(?:\\([^\\)]*\\))?"); + + /** + * A cache of the last {@link CompilationUnit} read from some attached + * source on disk. This is cached because, in some scenarios, the method + * {@link #getCompilationUnitFromDisk(File, ClassFile)} will be called for + * the same class many times in a row (such as to get method parameter + * info for all methods in a single class). + */ + private static CompilationUnit lastCUFromDisk; + + private static SourceLocation lastCUFileParam; + private static ClassFile lastCUClassFileParam; + + + /** + * Private constructor to prevent instantiation. + */ + private Util() { + } + + + private static final void appendDocCommentTail(StringBuilder sb, + StringBuilder tail) { + + StringBuilder params = null; + StringBuilder returns = null; + StringBuilder throwsItems = null; + StringBuilder see = null; + StringBuilder seeTemp = null; + StringBuilder since = null; + StringBuilder author = null; + StringBuilder version = null; + StringBuilder unknowns = null; + boolean inParams = false, inThrows = false, + inReturns = false, inSeeAlso = false, + inSince = false, inAuthor = false, + inVersion = false, inUnknowns = false; + + String[] st = tail.toString().split("[ \t\r\n\f]+"); + String token = null; + + int i = 0; + while (iParameters:

    "); + } + else { + params.append("
    "); + } + params.append("").append(token).append(" "); + inSeeAlso=false; + inParams = true; + inReturns = false; + inThrows = false; + inSince = false; + inAuthor = false; + inVersion = false; + inUnknowns = false; + } + else if ("@return".equals(token) && iReturns:

    "); + } + inSeeAlso=false; + inReturns = true; + inParams = false; + inThrows = false; + inSince = false; + inAuthor = false; + inVersion = false; + inUnknowns = false; + } + else if ("@see".equals(token) && iSee Also:

    "); + seeTemp = new StringBuilder(); + } + else { + if (seeTemp.length()>0) { + String temp = seeTemp.substring(0, seeTemp.length()-1); + //syntax is exactly the same as link + appendLinkTagText(see, temp); + } + see.append("
    "); + seeTemp.setLength(0); + //see.append("
    "); + } + inSeeAlso = true; + inReturns = false; + inParams = false; + inThrows = false; + inSince = false; + inAuthor = false; + inVersion = false; + inUnknowns = false; + } + else if (("@throws".equals(token)) || + ("@exception".equals(token)) && iThrows:

    "); + } + else { + throwsItems.append("
    "); + } + throwsItems.append("").append(token).append(" "); + inSeeAlso = false; + inParams = false; + inReturns = false; + inThrows = true; + inSince = false; + inAuthor = false; + inVersion = false; + inUnknowns = false; + } + else if ("@since".equals(token) && iSince:

    "); + } + inSeeAlso=false; + inReturns = false; + inParams = false; + inThrows = false; + inSince = true; + inAuthor = false; + inVersion = false; + inUnknowns = false; + } + else if ("@author".equals(token) && iAuthor:

    "); + } + else { + author.append("
    "); + } + inSeeAlso=false; + inReturns = false; + inParams = false; + inThrows = false; + inSince = false; + inAuthor = true; + inVersion = false; + inUnknowns = false; + } + else if ("@version".equals(token) && iVersion:

    "); + } + else { + version.append("
    "); + } + inSeeAlso=false; + inReturns = false; + inParams = false; + inThrows = false; + inSince = false; + inAuthor = false; + inVersion = true; + inUnknowns = false; + } + else if (token.startsWith("@") && token.length()>1) { + if (unknowns==null) { + unknowns = new StringBuilder(); + } + else { + unknowns.append("

    "); + } + unknowns.append("").append(token).append("

    "); + // Stop everything; unknown/unsupported tag + inSeeAlso = false; + inParams = false; + inReturns = false; + inThrows = false; + inSince = false; + inAuthor = false; + inVersion = false; + inUnknowns = true; + } + else if (inParams) { + params.append(token).append(' '); + } + else if (inReturns) { + returns.append(token).append(' '); + } + else if (inSeeAlso) { + //see.append(token).append(' '); + seeTemp.append(token).append(' '); + } + else if (inThrows) { + throwsItems.append(token).append(' '); + } + else if (inSince) { + since.append(token).append(' '); + } + else if (inAuthor) { + author.append(token).append(' '); + } + else if (inVersion) { + version.append(token).append(' '); + } + else if (inUnknowns) { + unknowns.append(token).append(' '); + } + } + + sb.append("

    "); + + if (params!=null) { + sb.append(params).append("

    "); + } + if (returns!=null) { + sb.append(returns).append("

    "); + } + if (throwsItems!=null) { + sb.append(throwsItems).append("

    "); + } + if (see!=null) { + if (seeTemp.length()>0) { // Last @see contents + String temp = seeTemp.substring(0, seeTemp.length()-1); + //syntax is exactly the same as link + appendLinkTagText(see, temp); + } + see.append("
    "); + sb.append(see).append("

    "); + } + if (author!=null) { + sb.append(author).append("

    "); + } + if (version!=null) { + sb.append(version).append("

    "); + } + if (since!=null) { + sb.append(since).append("

    "); + } + if (unknowns!=null) { + sb.append(unknowns).append("

    "); + } + + } + + + /** + * Appends HTML representing a "link" or "linkplain" Javadoc element to + * a string buffer.

    + * For some information on this format, see + * + * http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#see. + * + * @param appendTo The buffer to append to. + * @param linkContent The content of a "link", "linkplain" or "see" item. + */ + private static final void appendLinkTagText(StringBuilder appendTo, + String linkContent) { + linkContent = linkContent.trim(); // If "@link" and text on different lines + Matcher m = LINK_TAG_MEMBER_PATTERN.matcher(linkContent); + + if (m.find() && m.start() == 0) { + + appendTo.append("0) { // Not -1 + String prefix = match.substring(0, pound); + if ("java.lang.Object".equals(prefix)) { + text = match.substring(pound+1); + } + } + else { // Just use whole match (invalid link?) + // TODO: Could be just a class name. Find on classpath + text = match; + } + } + else { // match.length() < linkContent.length() + int offs = match.length(); + // Will usually skip just a single space + while (offs").append(text); + appendTo.append(""); + + } + + // @see + * This is a + * pre block + * + * @param dc The documentation comment. + * @return An HTML version of the comment. + */ + public static final String docCommentToHtml(String dc) { + + if (dc==null) { + return null; + } + if (dc.endsWith("*/")) { + dc = dc.substring(0, dc.length()-2); + } + + // First, strip the line transitions. These always seem to be stripped + // first from Javadoc, even when in between

     and 
    tags. + Matcher m = DOC_COMMENT_LINE_HEADER.matcher(dc); + dc = m.replaceAll("\n"); + + StringBuilder html = new StringBuilder( + ""); + StringBuilder tailBuf = null; + + BufferedReader r = new BufferedReader(new StringReader(dc)); + + try { + + // Handle the first line (guaranteed to be at least 1 line). + String line = r.readLine().substring(3); + line = possiblyStripDocCommentTail(line); + int offs = 0; + while (offs') { + result.append(">"); + } + else if (character == '\"') { + result.append("""); + } + else if (character == '\'') { + result.append("'"); + } + else if (character == '&') { + result.append("&"); + } + else { + //the char is not a special one + //add it to the result as is + result.append(character); + } + character = iterator.next(); + } + return result.toString(); + } + + + private static final StringBuilder fixDocComment(StringBuilder text) { + + // Nothing to do. + int index = text.indexOf("{@"); + if (index==-1) { + return text; + } + + StringBuilder sb = new StringBuilder(); + int textOffs = 0; + + do { + + int closingBrace = indexOf('}', text, index+2); + if (closingBrace>-1) { // Should practically always be true + + sb.append(text, textOffs, index); + String content = text.substring(index+2, closingBrace); + index = textOffs = closingBrace + 1; + + if (content.startsWith("code ")) { + sb.append(""). + append(forXML(content.substring(5))). + append(""); + } + + else if (content.startsWith("link ")) { + sb.append(""); + appendLinkTagText(sb, content.substring(5)); + sb.append(""); + } + + else if (content.startsWith("linkplain ")) { + appendLinkTagText(sb, content.substring(10)); + } + + else if (content.startsWith("literal ")) { + // TODO: Should escape HTML-breaking chars, such as '>'. + sb.append(content.substring(8)); + } + + else { // Unhandled Javadoc tag + sb.append("").append(content).append(""); + } + + } + else { + break; // Unclosed javadoc tag - just bail + } + + } while ((index=text.indexOf("{@", index))>-1); + + if (textOffsnull if it is not found + * or an IO error occurs. + */ + public static CompilationUnit getCompilationUnitFromDisk( + SourceLocation loc, ClassFile cf) { + + // Cached value? + if (loc==lastCUFileParam && cf==lastCUClassFileParam) { + //System.out.println("Returning cached CompilationUnit"); + return lastCUFromDisk; + } + + lastCUFileParam = loc; + lastCUClassFileParam = cf; + CompilationUnit cu = null; + + if(loc != null) { + try { + cu = loc.getCompilationUnit(cf); + } catch (IOException ioe) { + ioe.printStackTrace(); + } + } + + lastCUFromDisk = cu; + return cu; + + } + + + /** + * Returns the "unqualified" version of a (possibly) fully-qualified + * class name. + * + * @param clazz The class name. + * @return The unqualified version of the name. + */ + public static final String getUnqualified(String clazz) { + int dot = clazz.lastIndexOf('.'); + if (dot>-1) { + clazz = clazz.substring(dot+1); + } + return clazz; + } + + + /** + * Returns the next location of a single character in a character sequence. + * This method is here because StringBuilder doesn't get this + * method added to it until Java 1.5. + * + * @param ch The character to look for. + * @param sb The character sequence. + * @param offs The offset at which to start looking. + * @return The next location of the character, or -1 if it is not + * found. + */ + private static final int indexOf(char ch, CharSequence sb, int offs) { + while (offs.' character. + * + * @param str The string to check. + * @return Whether the string is fully qualified. + * @see #getUnqualified(String) + */ + public static final boolean isFullyQualified(String str) { + return str.indexOf('.')>-1; + } + + + /** + * Returns whether this line ends in the middle of a pre-block. + * + * @param line The line's contents. + * @param prevValue Whether this line started in a pre-block. + * @return Whether the line ends in a pre-block. + */ + private static final boolean isInPreBlock(String line, boolean prevValue) { + int lastPre = line.lastIndexOf("pre>"); + if (lastPre<=0) { + return prevValue; + } + char prevChar = line.charAt(lastPre-1); + if (prevChar=='<') { + return true; + } + else if (prevChar=='/' && lastPre>=2) { + if (line.charAt(lastPre-2)=='<') { + return false; + } + } + return prevValue; + } + + + /** + * Removes the tail end of a documentation comment from a string, if it + * exists. + * + * @param str The string. + * @return The string, possibly with the documentation comment tail + * removed. + */ + private static final String possiblyStripDocCommentTail(String str) { + if (str.endsWith("*/")) { + str = str.substring(0, str.length()-2); + } + return str; + } + + + /** + * A faster way to split on a single char than String#split(), since + * we'll be doing this in a tight loop possibly thousands of times (rt.jar). + * This is also fundamentally different than {@link String#split(String)}), + * in the case where str ends with ch - this + * method will return an empty item at the end of the returned array, while + * String#split() will not. + * + * @param str The string to split. + * @param ch The char to split on. + * @return The string, split on the character (e.g. '/' or + * '.'). + */ + public static final String[] splitOnChar(String str, int ch) { + List list = new ArrayList(3); + int pos = 0; + int old = 0; + while ((pos=str.indexOf(ch, old))>-1) { + list.add(str.substring(old, pos)); + old = pos+1; + } + // If str ends in ch, this adds an empty item to the end of the list. + // This is what we want. + list.add(str.substring(old)); + String[] array = new String[list.size()]; + return list.toArray(array); + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/buildpath/ClassEnumerationReader.java b/src/main/java/org/fife/rsta/ac/bsh/buildpath/ClassEnumerationReader.java new file mode 100644 index 00000000..648fa65b --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/buildpath/ClassEnumerationReader.java @@ -0,0 +1,112 @@ +/* + * 04/21/2012 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.buildpath; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; + + +/** + * Reads plain text files enumerating classes to take from the classpath and + * add to a {@link ClasspathLibraryInfo}. Files should have a format similar + * to the following: + * + *
    + * - com.mycompany.pkg1.Class1
    + * Class2
    + * Class3
    + * - com.mycompany.pkg2.Foo
    + * Bar
    + * - aonther.pkg.Utils
    + * ...
    + * 
    + * + * Such files are expected to be UTF-8. The exact file structure is as follows: + *
      + *
    • Lines that start with a "-" denote a fully-qualified + * class, interface, or enum name. + *
    • Lines following a line starting with "-" are simply a + * class, interface, or enum name, and are assumed to be in the same + * package as the previous class on the "-" line. + *
    • Blank lines and lines starting with "#" are ignored. + *
    + * + * @author Robert Futrell + * @version 1.0 + */ +public class ClassEnumerationReader { + + + /** + * Private constructor to prevent instantiation. + */ + private ClassEnumerationReader() { + } + + + /** + * Returns the list of classes specified in the given stream. + * + * @param in The input stream to read from. This will be closed when + * this method returns. + * @return The list of class names read. + * @throws IOException If an IO error occurs. + */ + public static List getClassNames(InputStream in) throws IOException { + + String lastPkg = null; + String line = null; + List classNames = new ArrayList(); + + BufferedReader r = new BufferedReader(new InputStreamReader(in, "UTF-8")); + try { + + while ((line=r.readLine())!=null) { + + // Skip blank lines and comments + line = line.trim(); + if (line.length()==0 || line.charAt(0)=='#') { + continue; + } + + // A new fully-qualified class name + if (line.charAt(0)=='-') { + line = line.substring(1).trim(); + classNames.add(line); + int lastDot = line.lastIndexOf('.'); + lastPkg = line.substring(0, lastDot+1); + } + + // Just a class name + else { + String className = line; + if (lastPkg!=null) { + className = lastPkg + className; + } + classNames.add(className); + } + + } + + } finally { + r.close(); + } + + return classNames; + + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/buildpath/ClasspathLibraryInfo.java b/src/main/java/org/fife/rsta/ac/bsh/buildpath/ClasspathLibraryInfo.java new file mode 100644 index 00000000..0ae8335f --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/buildpath/ClasspathLibraryInfo.java @@ -0,0 +1,220 @@ +/* + * 04/21/2012 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.buildpath; + +import java.io.BufferedInputStream; +import java.io.DataInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.fife.rsta.ac.bsh.PackageMapNode; +import org.fife.rsta.ac.bsh.classreader.ClassFile; + + +/** + * Information about specific classes on the current application's classpath to + * add to the "build path." This type of container is useful if your + * application ships with specific classes you want included in code + * completion, but you don't want to add the entire jar to the build path.

    + * + * Since there is no real way to determine all classes in a package via + * reflection, you must explicitly enumerate all classes that are on the + * classpath that you want on the build path. To make this easier, you can + * use the {@link ClassEnumerationReader} class to read a list of classes from + * a plain text file or other resource.

    + * + * If you're delivering the corresponding .java source files also on the + * classpath (i.e. you have a library "hard-coded" to be on the build path), + * you can set the source location to be a ClasspathSourceLocation + * to get the source located automatically. + * + * @author Robert Futrell + * @version 1.0 + * @see JarLibraryInfo + * @see DirLibraryInfo + * @see ClasspathSourceLocation + */ +public class ClasspathLibraryInfo extends LibraryInfo { + + /** + * Mapping of class names to ClassFiles. This information is + * cached even though it's also cached at the JarReader level + * because the class definitions are effectively immutable since they're + * on the classpath. This allows you to theoretically share a single + * ClasspathLibraryInfo across several different jar managers. + */ + private Map classNameToClassFile; + + + /** + * Constructor. + * + * @param classes A list of fully-qualified class names for classes you + * want added to the build path. + */ + public ClasspathLibraryInfo(String[] classes) { + this(Arrays.asList(classes), null); + } + + + /** + * Constructor. + * + * @param classes A list of fully-qualified class names for classes you + * want added to the build path. + */ + public ClasspathLibraryInfo(List classes) { + this(classes, null); + } + + + /** + * Constructor. + * + * @param classes A list of fully-qualified class names for classes you + * want added to the build path. + * @param sourceLoc The location of the source files for the classes given. + * This may be null. + */ + public ClasspathLibraryInfo(List classes, SourceLocation sourceLoc){ + setSourceLocation(sourceLoc); + classNameToClassFile = new HashMap(); + int count = classes==null ? 0 : classes.size(); + for (int i=0; i0. + * + * @return 0 always. + */ + @Override + public long getLastModified() { + return 0; + } + + + @Override + public String getLocationAsString() { + return null; + } + + + @Override + public int hashCode() { + return classNameToClassFile.hashCode(); + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/buildpath/ClasspathSourceLocation.java b/src/main/java/org/fife/rsta/ac/bsh/buildpath/ClasspathSourceLocation.java new file mode 100644 index 00000000..e844a36c --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/buildpath/ClasspathSourceLocation.java @@ -0,0 +1,70 @@ +/* + * 04/21/2012 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.buildpath; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +import org.fife.rsta.ac.bsh.classreader.ClassFile; +import org.fife.rsta.ac.bsh.rjc.ast.CompilationUnit; +import org.fife.rsta.ac.bsh.rjc.lexer.Scanner; +import org.fife.rsta.ac.bsh.rjc.parser.ASTFactory; + + +/** + * Represents Java source files somewhere on the classpath. This might be + * somewhat of a unique situation, since often source isn't on the classpath, + * only class files are. However, there may be times when you want to ship + * both the classes and source for a library and put them on your classpath + * for simplicity of integrating with this code completion library. In such a + * case, you would use a ClasspathLibraryInfo and use this class + * for the source location.

    + * + * This class has no state; any classes it's asked about, it assumes it can + * find the corresponding .java file somewhere on the classpath using the + * class's ClassLoader. + * + * @author Robert Futrell + * @version 1.0 + * @see ClasspathLibraryInfo + */ +public class ClasspathSourceLocation implements SourceLocation { + + + /** + * {@inheritDoc} + */ + public CompilationUnit getCompilationUnit(ClassFile cf) throws IOException { + + CompilationUnit cu = null; + + String res = cf.getClassName(true).replace('.', '/') + ".java"; + InputStream in = getClass().getClassLoader().getResourceAsStream(res); + if (in!=null) { + Scanner s = new Scanner(new InputStreamReader(in)); + cu = new ASTFactory().getCompilationUnit(res, s); + } + + return cu; + + } + + + /** + * {@inheritDoc} + */ + public String getLocationAsString() { + return null; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/buildpath/DirLibraryInfo.java b/src/main/java/org/fife/rsta/ac/bsh/buildpath/DirLibraryInfo.java new file mode 100644 index 00000000..e8cb4671 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/buildpath/DirLibraryInfo.java @@ -0,0 +1,195 @@ +/* + * 04/21/2012 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.buildpath; + +import java.io.File; +import java.io.IOException; + +import org.fife.rsta.ac.bsh.PackageMapNode; +import org.fife.rsta.ac.bsh.classreader.ClassFile; + + +/** + * Information about a folder containing a set of classes to add to the "build + * path." This type of library info could be used, for example, to add sibling + * projects in a workspace, not yet built into jars, to another project's build + * path. + * + * @author Robert Futrell + * @version 1.0 + * @see JarLibraryInfo + * @see ClasspathLibraryInfo + */ +public class DirLibraryInfo extends LibraryInfo { + + private File dir; + + + public DirLibraryInfo(File dir) { + this(dir, null); + } + + + public DirLibraryInfo(String dir) { + this(new File(dir)); + } + + + public DirLibraryInfo(File dir, SourceLocation sourceLoc) { + setDirectory(dir); + setSourceLocation(sourceLoc); + } + + + public DirLibraryInfo(String dir, SourceLocation sourceLoc) { + this(new File(dir), sourceLoc); + } + + + @Override + public void bulkClassFileCreationEnd() { + // Do nothing + } + + + @Override + public void bulkClassFileCreationStart() { + // Do nothing + } + + + /** + * Compares this LibraryInfo to another one. Two instances of + * this class are only considered equal if they represent the same class + * file location. Source attachment is irrelevant. + * + * @return The sort order of these two library infos. + */ + public int compareTo(LibraryInfo info) { + if (info==this) { + return 0; + } + int result = -1; + if (info instanceof DirLibraryInfo) { + return dir.compareTo(((DirLibraryInfo)info).dir); + } + return result; + } + + + @Override + public ClassFile createClassFile(String entryName) throws IOException { + return createClassFileBulk(entryName); + } + + + @Override + public ClassFile createClassFileBulk(String entryName) throws IOException { + File file = new File(dir, entryName); + if (!file.isFile()) { + System.err.println("ERROR: Invalid class file: " + file.getAbsolutePath()); + return null; + } + return new ClassFile(file); + } + + + @Override + public PackageMapNode createPackageMap() throws IOException { + PackageMapNode root = new PackageMapNode(); + getPackageMapImpl(dir, null, root); + return root; + } + + + @Override + public long getLastModified() { + return dir.lastModified(); + } + + + @Override + public String getLocationAsString() { + return dir.getAbsolutePath(); + } + + + /** + * Does the dirty-work of finding all class files in a directory tree. + * + * @param dir The directory to scan. + * @param pkg The package name scanned so far, in the form + * "com/company/pkgname"... + * @throws IOException If an IO error occurs. + */ + private void getPackageMapImpl(File dir, String pkg, PackageMapNode root) + throws IOException { + + File[] children = dir.listFiles(); + + for (int i=0; inull. + */ + private void setDirectory(File dir) { + if (dir==null || !dir.isDirectory()) { + String name = dir==null ? "null" : dir.getAbsolutePath(); + throw new IllegalArgumentException("Directory does not exist: " + name); + } + this.dir = dir; + } + + + /** + * Returns a string representation of this jar information. Useful for + * debugging. + * + * @return A string representation of this object. + */ + @Override + public String toString() { + return "[DirLibraryInfo: " + + "jar=" + dir.getAbsolutePath() + + "; source=" + getSourceLocation() + + "]"; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/buildpath/DirSourceLocation.java b/src/main/java/org/fife/rsta/ac/bsh/buildpath/DirSourceLocation.java new file mode 100644 index 00000000..1940b041 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/buildpath/DirSourceLocation.java @@ -0,0 +1,96 @@ +/* + * 04/21/2012 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.buildpath; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; + +import org.fife.rsta.ac.bsh.classreader.ClassFile; +import org.fife.rsta.ac.bsh.rjc.ast.CompilationUnit; +import org.fife.rsta.ac.bsh.rjc.lexer.Scanner; +import org.fife.rsta.ac.bsh.rjc.parser.ASTFactory; + + +/** + * Represents Java source in a directory, such as in a project's source folder. + * + * @author Robert Futrell + * @version 1.0 + */ +public class DirSourceLocation implements SourceLocation { + + private File dir; + + + /** + * Constructor. + * + * @param dir The directory containing the source files. + */ + public DirSourceLocation(String dir) { + this(new File(dir)); + } + + + /** + * Constructor. + * + * @param dir The directory containing the source files. + */ + public DirSourceLocation(File dir) { + this.dir = dir; + } + + + /** + * {@inheritDoc} + */ + public CompilationUnit getCompilationUnit(ClassFile cf) throws IOException { + + CompilationUnit cu = null; + + String entryName = cf.getClassName(true); + entryName = entryName.replace('.', '/'); + entryName += ".java"; + //System.out.println("DEBUG: entry name: " + entryName); + File file = new File(dir, entryName); + if (!file.isFile()) { + // Be nice and check for "src/" subdirectory + file = new File(dir, "src/" + entryName); + } + + if (file.isFile()) { + BufferedReader r = new BufferedReader(new FileReader(file)); + try { + Scanner s = new Scanner(r); + cu = new ASTFactory().getCompilationUnit(entryName, s); + //System.out.println("DEBUG: cu: " + cu); + } finally { + r.close(); + } + } + + return cu; + + } + + + /** + * {@inheritDoc} + */ + public String getLocationAsString() { + return dir.getAbsolutePath(); + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/buildpath/JarLibraryInfo.java b/src/main/java/org/fife/rsta/ac/bsh/buildpath/JarLibraryInfo.java new file mode 100644 index 00000000..a577746c --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/buildpath/JarLibraryInfo.java @@ -0,0 +1,214 @@ +/* + * 04/21/2012 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.buildpath; + +import java.io.BufferedInputStream; +import java.io.DataInputStream; +import java.io.File; +import java.io.IOException; +import java.util.Enumeration; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; +import java.util.zip.ZipEntry; + +import org.fife.rsta.ac.bsh.PackageMapNode; +import org.fife.rsta.ac.bsh.classreader.ClassFile; + + +/** + * Information about a jar of classes to add to the "build path." + * + * @author Robert Futrell + * @version 1.0 + * @see DirLibraryInfo + * @see ClasspathLibraryInfo + */ +public class JarLibraryInfo extends LibraryInfo { + + private File jarFile; + private JarFile bulkCreateJar; + + + public JarLibraryInfo(String jarFile) { + this(new File(jarFile)); + } + + + public JarLibraryInfo(File jarFile) { + this(jarFile, null); + } + + + public JarLibraryInfo(File jarFile, SourceLocation sourceLoc) { + setJarFile(jarFile); + setSourceLocation(sourceLoc); + } + + + @Override + public void bulkClassFileCreationEnd() { + try { + bulkCreateJar.close(); + } catch (IOException ioe) { + ioe.printStackTrace(); + } + } + + + @Override + public void bulkClassFileCreationStart() { + try { + bulkCreateJar = new JarFile(jarFile); + } catch (IOException ioe) { + ioe.printStackTrace(); + } + } + + + /** + * Compares this LibraryInfo to another one. Two instances of + * this class are only considered equal if they represent the same class + * file location. Source attachment is irrelevant. + * + * @return The sort order of these two library infos. + */ + public int compareTo(LibraryInfo info) { + if (info==this) { + return 0; + } + int result = -1; + if (info instanceof JarLibraryInfo) { + result = jarFile.compareTo(((JarLibraryInfo)info).jarFile); + } + return result; + } + + + @Override + public ClassFile createClassFile(String entryName) throws IOException { + JarFile jar = new JarFile(jarFile); + try { + return createClassFileImpl(jar, entryName); + } finally { + jar.close(); + } + } + + + @Override + public ClassFile createClassFileBulk(String entryName) throws IOException { + return createClassFileImpl(bulkCreateJar, entryName); + } + + + private static final ClassFile createClassFileImpl(JarFile jar, + String entryName) throws IOException { + JarEntry entry = (JarEntry)jar.getEntry(entryName); + if (entry==null) { + System.err.println("ERROR: Invalid entry: " + entryName); + return null; + } + DataInputStream in = new DataInputStream( + new BufferedInputStream(jar.getInputStream(entry))); + ClassFile cf = null; + try { + cf = new ClassFile(in); + } finally { + in.close(); + } + return cf; + } + + + @Override + public PackageMapNode createPackageMap() throws IOException { + + PackageMapNode root = new PackageMapNode(); + JarFile jar = new JarFile(jarFile); + + try { + + Enumeration e = jar.entries(); + while (e.hasMoreElements()) { + ZipEntry entry = e.nextElement(); + String entryName = entry.getName(); + if (entryName.endsWith(".class")) { + root.add(entryName); + } + } + + } finally { + jar.close(); + } + + return root; + + } + + + @Override + public long getLastModified() { + return jarFile.lastModified(); + } + + + @Override + public String getLocationAsString() { + return jarFile.getAbsolutePath(); + } + + + /** + * Returns the jar file this instance is wrapping. + * + * @return The jar file. + */ + public File getJarFile() { + return jarFile; + } + + + @Override + public int hashCode() { + return jarFile.hashCode(); + } + + + /** + * Sets the jar file location. + * + * @param jarFile The jar file location. This cannot be null. + */ + private void setJarFile(File jarFile) { + if (jarFile==null || !jarFile.exists()) { + String name = jarFile==null ? "null" : jarFile.getAbsolutePath(); + throw new IllegalArgumentException("Jar does not exist: " + name); + } + this.jarFile = jarFile; + } + + + /** + * Returns a string representation of this jar information. Useful for + * debugging. + * + * @return A string representation of this object. + */ + @Override + public String toString() { + return "[JarLibraryInfo: " + + "jar=" + jarFile.getAbsolutePath() + + "; source=" + getSourceLocation() + + "]"; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/buildpath/LibraryInfo.java b/src/main/java/org/fife/rsta/ac/bsh/buildpath/LibraryInfo.java new file mode 100644 index 00000000..e11b4ba7 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/buildpath/LibraryInfo.java @@ -0,0 +1,283 @@ +/* + * 04/21/2012 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.buildpath; + +import java.io.File; +import java.io.IOException; + +import org.fife.rsta.ac.bsh.PackageMapNode; +import org.fife.rsta.ac.bsh.classreader.ClassFile; + + +/** + * Information about a jar, compiled class folder, or other source of classes + * to add to the "build path" for Java completion. Instances of this class are + * added to a {@link JarManager} for each library that should be on the build + * path.

    + * + * This class also keeps track of an optional source location, such as a zip + * file or source folder. If defined, this location is used to find the .java + * source corresponding to the library's classes, which is used to display + * Javadoc comments during code completion. + * + * @author Robert Futrell + * @version 1.0 + * @see DirLibraryInfo + * @see JarLibraryInfo + * @see ClasspathLibraryInfo + */ +public abstract class LibraryInfo implements Comparable, + Cloneable { + + /** + * The location of the source files corresponding to this library. This + * may be null. + */ + private SourceLocation sourceLoc; + + + /** + * Does any cleanup necessary after a call to + * {@link #bulkClassFileCreationStart()}. + * + * @throws IOException If an IO error occurs. + * @see #bulkClassFileCreationStart() + * @see #createClassFileBulk(String) + */ + public abstract void bulkClassFileCreationEnd() throws IOException; + + + /** + * Readies this library for many class files being fetched via + * {@link #createClassFileBulk(String)}. After calling this method, + * the actual class file fetching should be done in a try/finally block + * that ensures a call to {@link #bulkClassFileCreationEnd()}; e.g. + * + *

    +	 * libInfo.bulkClassFileCreationStart();
    +	 * try {
    +	 *    String entryName = ...;
    +	 *    ClassFile cf = createClassFileBulk(entryName);
    +	 *    ...
    +	 * } finally {
    +	 *    libInfo.bulkClassFileCreationEnd();
    +	 * }
    +	 * 
    + * + * @throws IOException If an IO error occurs. + * @see #bulkClassFileCreationEnd() + * @see #createClassFileBulk(String) + */ + public abstract void bulkClassFileCreationStart() throws IOException; + + + /** + * Returns a deep copy of this library. + * + * @return A deep copy. + */ + @Override + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException cnse) { // Never happens + throw new IllegalStateException( + "Doesn't support cloning, but should! - " + getClass().getName()); + } + } + + + /** + * Returns the class file information for the specified class. Instances + * of JarReader can call this method to lazily load + * information on individual classes and shove it into their package maps. + *

    + * If many class files will be fetched at a time, you should prefer using + * {@link #bulkClassFileCreationStart()} and + * {@link #createClassFileBulk(String)} over this method, for performance + * reasons. + * + * @param entryName The fully qualified name of the class file. + * @return The class file, or null if it isn't found in this + * library. + * @throws IOException If an IO error occurs. + * @see #createClassFileBulk(String) + */ + public abstract ClassFile createClassFile(String entryName) throws IOException; + + + /** + * Returns the class file information for the specified class. Instances + * of JarReader can call this method to lazily load + * information on individual classes and shove it into their package maps. + *

    + * This method should be used when multiple classes will be fetched from + * this library at the same time. It should only be called after a call to + * {@link #bulkClassFileCreationStart()}. If only a single class file is + * being fetched, it is simpler to call {@link #createClassFile(String)}. + * + * @param entryName The fully qualified name of the class file. + * @return The class file, or null if it isn't found in this + * library. + * @throws IOException If an IO error occurs. + * @see #createClassFile(String) + */ + public abstract ClassFile createClassFileBulk(String entryName) + throws IOException; + + + /** + * Creates and returns a map of maps representing the hierarchical package + * structure in this library. + * + * @return The package structure in this library. + * @throws IOException If an IO error occurs. + */ + public abstract PackageMapNode createPackageMap() throws IOException; + + + /** + * Two LibraryInfos are considered equal if they represent + * the same class file location. Source attachment is irrelevant. + * + * @return Whether the specified instance represents the same class + * source as this one. + */ + @Override + public boolean equals(Object o) { + return o instanceof LibraryInfo && + compareTo((LibraryInfo)o)==0; + } + + + /** + * Returns information on the "main" jar for a JRE. This will be + * rt.jar everywhere except OS X, where it will be + * classes.jar. The associated source zip/jar file is also + * checked for. + * + * @return The information, or null if there is not a JRE in + * the specified directory. + * @see #getMainJreJarInfo() + */ + public static LibraryInfo getJreJarInfo(File jreHome) { + + LibraryInfo info = null; + + File mainJar = new File(jreHome, "lib/rt.jar"); // Sun JRE's + File sourceZip = null; + + if (mainJar.isFile()) { // Sun JRE's + sourceZip = new File(jreHome, "src.zip"); + if (!sourceZip.isFile()) { + // Might be a JRE inside a JDK + sourceZip = new File(jreHome, "../src.zip"); + } + } + + else { // Might be OS X + mainJar = new File(jreHome, "../Classes/classes.jar"); + // ${java.home}/src.jar is the common location on OS X. + sourceZip = new File(jreHome, "src.jar"); + } + + if (mainJar.isFile()) { + info = new JarLibraryInfo(mainJar); + if (sourceZip.isFile()) { // Make sure our last guess actually exists + info.setSourceLocation(new ZipSourceLocation(sourceZip)); + } + } + else { + System.err.println("[ERROR]: Cannot locate JRE jar in " + + jreHome.getAbsolutePath()); + mainJar = null; + } + + return info; + + } + + + /** + * Returns the time this library was last modified. For jar files, this + * would be the modified date of the file. For directories, this would be + * the time a file in the directory was most recently modified. This + * information is used to determine whether callers should clear their + * cached package map information and load it anew.

    + * + * This API may change in the future. + * + * @return The last time this library was modified. + */ + public abstract long getLastModified(); + + + /** + * Returns the location of this library, as a string. If this library + * is contained in a single jar file, this will be the full path to that + * jar. If it is a directory containing classes, it will be the full path + * of the directory. Otherwise, this value will be null. + * + * @return The location of this library. + */ + public abstract String getLocationAsString(); + + + /** + * Returns information on the JRE running this application. This will be + * rt.jar everywhere except OS X, where it will be + * classes.jar. The associated source zip/jar file is also + * checked for. + * + * @return The information, or null if an error occurs. + * @see #getJreJarInfo(File) + */ + public static LibraryInfo getMainJreJarInfo() { + String javaHome = System.getProperty("java.home"); + return getJreJarInfo(new File(javaHome)); + } + + + /** + * Returns the location of the source corresponding to this library. + * + * @return The source for this library, or null if none. + * @see #setSourceLocation(SourceLocation) + */ + public SourceLocation getSourceLocation() { + return sourceLoc; + } + + + /** + * Subclasses should override this method since {@link #equals(Object)} is + * overridden. Instances of LibraryInfo aren't typically + * stored in maps, so the hash value isn't necessarily important to + * RSTALanguageSupport. + * + * @return The hash code for this library. + */ + @Override + public abstract int hashCode(); + + + /** + * Sets the location of the source corresponding to this library. + * + * @param sourceLoc The source location. This may be null. + * @see #getSourceLocation() + */ + public void setSourceLocation(SourceLocation sourceLoc) { + this.sourceLoc = sourceLoc; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/buildpath/SourceLocation.java b/src/main/java/org/fife/rsta/ac/bsh/buildpath/SourceLocation.java new file mode 100644 index 00000000..7c6255ef --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/buildpath/SourceLocation.java @@ -0,0 +1,53 @@ +/* + * 04/21/2012 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.buildpath; + +import java.io.IOException; + +import org.fife.rsta.ac.bsh.classreader.ClassFile; +import org.fife.rsta.ac.bsh.rjc.ast.CompilationUnit; + + +/** + * Represents the location of Java source, either in a zip file (src.zip), + * a flat file (source in a project's source folder), or in some other location. + * + * @author Robert Futrell + * @version 1.0 + * @see DirSourceLocation + * @see ZipSourceLocation + * @see ClasspathSourceLocation + */ +public interface SourceLocation { + + + /** + * Returns an AST for the specified class file. + * + * @param cf The class file to grab the AST for. + * @return The AST, or null if it cannot be found. + * @throws IOException If an IO error occurs. + */ + CompilationUnit getCompilationUnit(ClassFile cf) throws IOException; + + + /** + * Returns a string representation of this source location. For locations + * on disk such as zip files or directories, this should be the full path + * to the resource. + * + * @return The location of this source as a string, or null if + * it is not an accessible location. + */ + public String getLocationAsString(); + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/buildpath/ZipSourceLocation.java b/src/main/java/org/fife/rsta/ac/bsh/buildpath/ZipSourceLocation.java new file mode 100644 index 00000000..60b3c0ca --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/buildpath/ZipSourceLocation.java @@ -0,0 +1,104 @@ +/* + * 04/21/2012 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.buildpath; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +import org.fife.rsta.ac.bsh.classreader.ClassFile; +import org.fife.rsta.ac.bsh.rjc.ast.CompilationUnit; +import org.fife.rsta.ac.bsh.rjc.lexer.Scanner; +import org.fife.rsta.ac.bsh.rjc.parser.ASTFactory; + + +/** + * Represents source inside a zip or jar file. The source can be either in + * a "src/" subfolder, or at the root level of the archive. This + * class is useful for the JDK or other libraries that come with a + * src.zip file (src.jar on OS X). + * + * @author Robert Futrell + * @version 1.0 + */ +public class ZipSourceLocation implements SourceLocation { + + private File archive; + + + /** + * Constructor. + * + * @param archive The archive containing the source. This should be an + * absolute path to ensure correctness. + */ + public ZipSourceLocation(String archive) { + this(new File(archive)); + } + + + /** + * Constructor. + * + * @param archive The archive containing the source. + */ + public ZipSourceLocation(File archive) { + this.archive = archive; + } + + + /** + * {@inheritDoc} + */ + public CompilationUnit getCompilationUnit(ClassFile cf) throws IOException { + + CompilationUnit cu = null; + + ZipFile zipFile = new ZipFile(archive); + + try { + + String entryName = cf.getClassName(true).replaceAll("\\.", "/"); + entryName += ".java"; + //System.out.println("DEBUG: entry name: " + entryName); + ZipEntry entry = zipFile.getEntry(entryName); + if (entry == null) { + // Seen in some src.jar files, for example OS X's src.jar + entry = zipFile.getEntry("src/" + entryName); + } + + if (entry != null) { + InputStream in = zipFile.getInputStream(entry); + Scanner s = new Scanner(new InputStreamReader(in)); + cu = new ASTFactory().getCompilationUnit(entryName, s); + } + + } finally { + zipFile.close(); // Closes the input stream too + } + + return cu; + + } + + + /** + * {@inheritDoc} + */ + public String getLocationAsString() { + return archive.getAbsolutePath(); + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/AccessFlags.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/AccessFlags.java new file mode 100644 index 00000000..f116668c --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/classreader/AccessFlags.java @@ -0,0 +1,109 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.classreader; + + +/** + * Class/interface access flag masks. + * + * @author Robert Futrell + * @version 1.0 + */ +public interface AccessFlags { + + /** + * Declared public; may be accessed from outside its package. + */ + public static final int ACC_PUBLIC = 0x0001; + + /** + * Declared private; usable only within the defining class. + */ + public static final int ACC_PRIVATE = 0x0002; + + /** + * Declared protected; may be accessed within subclasses. + */ + public static final int ACC_PROTECTED = 0x0004; + + /** + * Declared static. + */ + public static final int ACC_STATIC = 0x0008; + + /** + * Declared final; no subclasses allowed. + */ + public static final int ACC_FINAL = 0x0010; + + /** + * Treat superclass methods specially when invoked by the + * invokespecial instruction. + */ + /* + * NOTE: This is the same value as ACC_SYNCHRONIZED. + */ + public static final int ACC_SUPER = 0x0020; + + /** + * Declared synchronized; invocation is wrapped in a monitor block. + */ + /* + * NOTE: This is the same value as ACC_SUPER. + */ + public static final int ACC_SYNCHRONIZED = 0x0020; + + /** + * Declared volatile; cannot be cached. + */ + public static final int ACC_VOLATILE = 0x0040; + + /** + * Declared transient; not written or read by a persistent object manager. + */ + public static final int ACC_TRANSIENT = 0x0080; + + /** + * Declared native; implemented in a language other than Java. + */ + public static final int ACC_NATIVE = 0x0100; + + /** + * Is an interface, not a class. + */ + public static final int ACC_INTERFACE = 0x0200; + + /** + * Declared abstract; may not be instantiated. + */ + public static final int ACC_ABSTRACT = 0x0400; + + /** + * Declared strictfp; floating-point mode is FP-strict. + */ + public static final int ACC_STRICT = 0x0800; + + /** + * Declared syntheticClassFile structure. + * + * @author Robert Futrell + * @version 1.0 + */ +public class ClassFile implements AccessFlags { + + private static final boolean DEBUG = false; + + /** + * The class file's minor version number. + */ + private int minorVersion; // u2 + + /** + * The class file's major version number. + */ + private int majorVersion; // u2 + + /** + * Constant pool infos. + */ + private ConstantPoolInfo[] constantPool; // Length constant_pool_count-1 !! + + /** + * Permissions and properties of this class or interface. + */ + private int accessFlags; // u2 + + /** + * Index into {@link #constantPool} for a ConstantClassInfo + * structure representing the class or interface defined in this class file. + */ + private int thisClass; // u2 + + /** + * Index into {@link #constantPool} for a ConstantClassInfo + * structure representing the superclass of this class or interface. If + * this value is 0 then this class must be class + * java.lang.Object. If this is an interface, then this index + * must point to information about class java.lang.Object. + */ + private int superClass; // u2 + + /** + * Indices into {@code constantPool} for ConstantClassInfos + * representing the implemented interfaces of this class or interface. + */ + int[] interfaces; // u2[] + + /** + * Structures giving complete descriptions of the fields in this class + * or interface. + */ + private FieldInfo[] fields; + + /** + * Structures giving complete descriptions of the methods in this class or + * interface. + */ + private MethodInfo[] methods; + + /** + * Whether this class is deprecated. + */ + private boolean deprecated; + + /** + * Attributes of this class or interface. + */ + private AttributeInfo[] attributes; + + /** + * Parameter types, such as "String" in List<String>. + */ + private List paramTypes; + + /** + * A mapping of type parameters to type arguments. This is set via + * {@link #setTypeParamsToTypeArgs(Map)} during code completion of members of an + * instance variable whose type is represented by this class file. This + * ClassFile doesn't use this field itself; rather, it's there + * for consumers (such as the Java code completion API) to use. + */ + private Map typeMap; + + public static final String DEPRECATED = "Deprecated"; + public static final String ENCLOSING_METHOD = "EnclosingMethod"; + public static final String INNER_CLASSES = "InnerClasses"; + public static final String RUNTIME_VISIBLE_ANNOTATIONS = "RuntimeVisibleAnnotations"; + public static final String SIGNATURE = "Signature"; + public static final String SOURCE_FILE = "SourceFile"; + public static final String BOOTSTRAP_METHODS = "BootstrapMethods"; + + /** + * The 4-byte class file header, "CAFEBABE". + */ + private static final byte[] HEADER = { (byte)0xCA, (byte)0xFE, + (byte)0xBA, (byte)0xBE }; + + + public ClassFile(File classFile) throws IOException { + DataInputStream in = new DataInputStream(new BufferedInputStream( + new FileInputStream(classFile))); + try { + init(in); + } finally { + in.close(); + } + } + + + public ClassFile(DataInputStream in) throws IOException { + init(in); + } + + + private void debugPrint(String text) { + if (DEBUG) { + System.out.println(text); + } + } + + + /** + * Returns the access flags for this class or interface. + * + * @return The access flags, as a bit field. + * @see AccessFlags + */ + public int getAccessFlags() { + return accessFlags; + } + + + /** + * Returns the specified attribute of this class file. + * + * @param index The index of the attribute. + * @return The attribute. + * @see #getAttributeCount() + */ + public AttributeInfo getAttribute(int index) { + return attributes[index]; + } + + + /** + * Returns the number of attributes of this class file. + * + * @return The number of attributes. + * @see #getAttribute(int) + */ + public int getAttributeCount() { + return attributes==null ? 0 : attributes.length; + } + + + /** + * Returns the name of this class or interface. + * + * @param fullyQualified Whether the name should be fully-qualified. + * @return The name of this class or interface. + * @see #getSuperClassName(boolean) + */ + public String getClassName(boolean fullyQualified) { + return getClassNameFromConstantPool(thisClass, fullyQualified); + } + + + /** + * Given an index into the constant pool of a {@link ConstantClassInfo}, + * this method returns the fully-qualified name of the class it points to. + * + * @param cpIndex The index into the constant pool. Note that + * this value is 1-based. + * @param fullyQualified Whether the returned class name should be fully + * qualified. + * @return The fully-qualified class or interface name. + */ + protected String getClassNameFromConstantPool(int cpIndex, + boolean fullyQualified) { + + ConstantPoolInfo cpi = getConstantPoolInfo(cpIndex); + + if (cpi instanceof ConstantClassInfo) { + ConstantClassInfo cci = (ConstantClassInfo)cpi; + int index = cci.getNameIndex(); + ConstantUtf8Info cui = (ConstantUtf8Info)getConstantPoolInfo(index); + String className = cui.getRepresentedString(false); + if (fullyQualified) { + className = className.replace('/', '.'); + } + else { + className = className.substring(className.lastIndexOf('/')+1); + } + return className.replace('$', '.'); + } + + // cpi is never null + throw new InternalError("Expected ConstantClassInfo, found " + + cpi.getClass().toString()); + + } + + + /** + * Returns the size of the constant pool, plus 1. + * + * @return The size of the constant pool, plus 1. + * @see #getConstantPoolInfo(int) + */ + public int getConstantPoolCount() { + return constantPool.length + 1; + } + + + /** + * Returns the constant pool entry at the specified index. Note that + * constant pool entries are 1-based (that is, valid indices + * are 1 - getConstantPoolCount()-1). + * + * @param index The index into the constant pool to retrieve. + * @return The constant pool entry, or null if + * index is 0 (e.g. this + * ClassFile object represents + * java.lang.Object). + * @see #getConstantPoolCount() + */ + public ConstantPoolInfo getConstantPoolInfo(int index) { + return index!=0 ? constantPool[index-1] : null; + } + + + /** + * Returns the number of fields declared in this class file. + * + * @return The number of fields. + * @see #getFieldInfo(int) + */ + public int getFieldCount() { + return fields==null ? 0 : fields.length; + } + + + /** + * Returns the specified field's information. + * + * @param index The index of the field info. + * @return The field's information. + * @see #getFieldCount() + * @see #getFieldInfoByName(String) + */ + public FieldInfo getFieldInfo(int index) { + return fields[index]; + } + + + /** + * Returns a field's information by name. + * + * @param name The name of the field. + * @return The field's information. + * @see #getFieldCount() + * @see #getFieldInfo(int) + */ + public FieldInfo getFieldInfoByName(String name) { + for (int i=0; inull + * if none. This is a list of {@link MethodInfo}s. + * @see #getMethodInfoByName(String, int) + */ + public List getMethodInfoByName(String name) { + return getMethodInfoByName(name, -1); + } + + + /** + * Returns all method overloads with the specified name and number of + * arguments. + * + * @param name The method name. + * @param argCount The number of arguments. If this is less than zero, + * all overloads will be returned, regardless of argument count. + * @return Any method overloads with the given name and argument count, or + * null if none. This is a list of + * {@link MethodInfo}s. + * @see #getMethodInfoByName(String) + */ + public List getMethodInfoByName(String name, int argCount) { + List methods = null; + for (int i=0; i(1); // Usually just 1 + } + methods.add(info); + } + } + } + return methods; + } + + + /** + * Returns the package for this class or interface. + * + * @return The package, or null if this class or interface + * is not in a package. + * @see #getClassName(boolean) + */ + public String getPackageName() { + String className = getClassName(true); + int dot = className.lastIndexOf('.'); + return dot==-1 ? null : className.substring(0, dot); + } + + + public List getParamTypes() { + return paramTypes; + } + + + /** + * Returns the fully-qualified name of the superclass of this class or + * interface. + * + * @param fullyQualified Whether the returned value should be fully + * qualified. + * @return The name of the superclass of this class or interface. If this + * is an interface, then "java.lang.Object" is + * returned. If this class file represents + * java.lang.Object, then null is + * returned. + * @see #getClassName(boolean) + */ + public String getSuperClassName(boolean fullyQualified) { + if (superClass==0) { // This is java.lang.Object + return null; + } + return getClassNameFromConstantPool(superClass, fullyQualified); + } + + + /** + * Returns the currently set type argument for the specified type parameter. + * + * @param typeParam The type parameter. + * @return The type argument, or "Object" if no type + * parameters have been set. This is because, if the user types, + * say, "java.util.List list;" in Java 5+, the + * type defaults to Object. The code completion API + * may set the type argument mapping to null if no + * type arguments are scanned, thus we need to return + * Object in this case. + * @see #setTypeParamsToTypeArgs(Map) + */ + public String getTypeArgument(String typeParam) { + // If no type arguments are specified for a class that's supposed to + // have them (according to calling code), return "Object", as Java + // assumes this. + return typeMap==null ? "Object" : (String)typeMap.get(typeParam); + } + + + /** + * Returns the string value represented by a ConstantUtf8Info + * entry in the constant pool. + * + * @param index The index into the constant pool of a + * ConstantUtf8Info structure. This should be + * 1-based. + * @return The string represented. + */ + public String getUtf8ValueFromConstantPool(int index) { + ConstantPoolInfo cpi = getConstantPoolInfo(index); + ConstantUtf8Info cui = (ConstantUtf8Info)cpi; + return cui.getRepresentedString(false); + } + + + /** + * Returns the version number of this class, as a string. + * + * @return The class's version number, in the form + * major.minor. + */ + public String getVersionString() { + return majorVersion + "." + minorVersion; + } + + + /** + * Parses the class file from a given input stream. + * + * @param in + * @throws IOException If an error occurs reading the class file. + */ + private void init(DataInputStream in) throws IOException { + readHeader(in); + readVersion(in); + readConstantPoolInfos(in); + readAccessFlags(in); + readThisClass(in); + readSuperClass(in); + readInterfaces(in); + readFields(in); + readMethods(in); + readAttributes(in); + } + + + /** + * Returns whether this class is deprecated. + * + * @return Whether this class is deprecated. + */ + public boolean isDeprecated() { + return deprecated; + } + + + /** + * Reads this class or interface's access flags. + * + * @param in + * @throws IOException If an error occurs reading the access flags. + */ + private void readAccessFlags(DataInputStream in) throws IOException { + accessFlags = in.readUnsignedShort(); + debugPrint("Access flags: " + accessFlags); + } + + + /** + * Reads a single attribute of this class file. + * + * @param in The input stream to read from. + * @return The attribute. + * @throws IOException If an IO error occurs. + */ + private AttributeInfo readAttribute(DataInputStream in) throws IOException { + + AttributeInfo ai = null; + + int attributeNameIndex = in.readUnsignedShort(); + int attributeLength = in.readInt(); + + String attrName = getUtf8ValueFromConstantPool(attributeNameIndex); + debugPrint("Found class attribute: " + attrName); + + if (SOURCE_FILE.equals(attrName)) { // 4.7.7 + int sourceFileIndex = in.readUnsignedShort(); + SourceFile sf = new SourceFile(this, sourceFileIndex); + ai = sf; + } + + else if (BOOTSTRAP_METHODS.equals(attrName)) { // 4.7.23 + //String name = getClassFile().getClassName(false) + "." + getName(); + //System.out.println(name + ": Attribute " + attrName + " not supported"); + Util.skipBytes(in, attributeLength); + //ai = null; + } + + else if (SIGNATURE.equals(attrName)) { // 4.8.8 + int signatureIndex = in.readUnsignedShort(); + String sig = getUtf8ValueFromConstantPool(signatureIndex); + //System.out.println("... Signature: " + sig); + ai = new Signature(this, sig); + paramTypes = ((Signature)ai).getClassParamTypes(); + } + + else if (INNER_CLASSES.equals(attrName)) { // 4.8.5 + //String name = getClassName(false) + "." + getName(); + //System.out.println(name + ": Attribute " + attrName + " not supported"); + Util.skipBytes(in, attributeLength); + //ai = null; + } + + else if (ENCLOSING_METHOD.equals(attrName)) { // 4.8.6 + //String name = getClassName(false) + "." + getName(); + //System.out.println(name + ": Attribute " + attrName + " not supported"); + Util.skipBytes(in, attributeLength); // 2 u2's, class_index and method_index + //ai = null; + } + + else if (DEPRECATED.equals(attrName)) { // 4.7.10 + // No need to read anything else, attributeLength==0 + deprecated = true; + } + + else if (RUNTIME_VISIBLE_ANNOTATIONS.equals(attrName)) { // 4.8.15 + //String name = getClassFile().getClassName(false) + "." + getName(); + //System.out.println(name + ": Attribute " + attrName + " not supported"); + Util.skipBytes(in, attributeLength); + //ai = null; + } + + // TODO: Handle other useful Attribute types, if any. + + else { // An unknown/unsupported attribute. + System.out.println("Unsupported class attribute: "+ attrName); + ai = AttributeInfo.readUnsupportedAttribute(this, in, attrName, + attributeLength); + } + + return ai; + + } + + + /** + * Reads this class file's attributes. + * + * @param in The input stream to read from. + * @throws IOException If an IO error occurs. + */ + private void readAttributes(DataInputStream in) throws IOException { + int attributeCount = in.readUnsignedShort(); + if (attributeCount>0) { + attributes = new AttributeInfo[attributeCount]; + for (int i=0; i0) { + fields = new FieldInfo[fieldCount]; + for (int i=0; i0xCAFEBABE class file header. + * + * @param in + * @throws IOException If the header is invalid. + */ + private void readHeader(DataInputStream in) throws IOException { + for (int i=0; i0) { + interfaces = new int[interfaceCount]; + for (int i=0; i0) { + methods = new MethodInfo[methodCount]; + for (int i=0; iClassFile + * does not directly use this field; it is there for code completion API's + * to use to extract the necessary types of arguments, return values, etc., + * of methods (see the {@link MethodInfo} class). + * + * @param typeMap A mapping of type parameters to type arguments (both + * Strings). + * @see #getTypeArgument(String) + */ + public void setTypeParamsToTypeArgs(Map typeMap) { + this.typeMap = typeMap; + for (int i=0; icatch or finally block (the section of code it + * covers, the type of Throwable it handles, and the location of the + * exception handler code). + * + * @author Robert Futrell + * @version 1.0 + */ +public class ExceptionTableEntry { + + /** + * The parent class file. + */ + private ClassFile cf; + + /** + * Start of the range in the code array at which the exception handler is + * active. + */ + private int startPC; // u2 + + /** + * End of the range in the code array at which the exception handler is + * active. This value must be either a valid index into the code array of + * the opcode of an instruction, or be equal to + * {@link Code#getCodeLength()}. + */ + private int endPC; // u2 + + /** + * The start of the exception handler. This value must be a valid index + * into the code array and must be the index of the opcode of an + * instruction. + */ + private int handlerPC; // u2 + + /** + * If the value of {@link #catchType} is nonzero, it must be a valid + * index into the constant pool. The constant pool entry at that index + * must be a {@link ConstantClassInfo} structure representing a class of + * exceptions that this exception handler is designated to catch. This + * class must be the class Throwable or one of its subclasses. + * The exception handler will be called only if the thrown exception is + * an instance of the given class or one of its subclasses.

    + * + * If the value of {@link #catchType} is zero, this exception handler is + * for all exceptions. This is used to implement finally. + */ + private int catchType; // u2 + + + /** + * Constructor. + * + * @param cf The parent class file. + */ + public ExceptionTableEntry(ClassFile cf) { + this.cf = cf; + } + + + /** + * Returns the name of the Throwable type caught and handled + * by this exception handler. + * + * @param fullyQualified Whether the name should be fully qualified. + * @return The name of the Throwable type, or null + * if this entry denotes a finally block. + */ + public String getCaughtThrowableType(boolean fullyQualified) { + return catchType==0 ? null : + cf.getClassNameFromConstantPool(catchType, fullyQualified); + } + + + public int getEndPC() { + return endPC; + } + + + public int getHandlerPC() { + return handlerPC; + } + + + public int getStartPC() { + return startPC; + } + + + /** + * Reads an exception table entry from an input stream. + * + * @param cf The class file. + * @param in The input stream to read from. + * @return The exception table entry. + * @throws IOException If an IO error occurs. + */ + public static ExceptionTableEntry read(ClassFile cf, DataInputStream in) + throws IOException { + ExceptionTableEntry entry = new ExceptionTableEntry(cf); + entry.startPC = in.readUnsignedShort(); + entry.endPC = in.readUnsignedShort(); + entry.handlerPC = in.readUnsignedShort(); + entry.catchType = in.readUnsignedShort(); + return entry; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/FieldInfo.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/FieldInfo.java new file mode 100644 index 00000000..73cd531e --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/classreader/FieldInfo.java @@ -0,0 +1,279 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.classreader; + +import org.fife.rsta.ac.bsh.classreader.attributes.ConstantValue; +import org.fife.rsta.ac.bsh.classreader.attributes.AttributeInfo; +import java.io.*; +import java.util.*; + + + +/** + * Represents a "field_info" structure as defined by the Java VM spec. + * + * @author Robert Futrell + * @version 1.0 + */ +public class FieldInfo extends MemberInfo { + + /** + * Index into the constant pool of a {@link ConstantUtf8Info} structure + * representing the field name, as a simple name. + */ + private int nameIndex; // u2 + + /** + * Index into the constant pool of a {@link ConstantUtf8Info} structure + * representing a valid field descriptor. + */ + private int descriptorIndex; // u2 + + /** + * An array of attributes of this field. + */ + private List attributes; + + public static final String CONSTANT_VALUE = "ConstantValue"; + + + /** + * Constructor. + * + * @see AccessFlags + */ + public FieldInfo(ClassFile cf, int accessFlags, int nameIndex, + int descriptorIndex) { + super(cf, accessFlags); + this.nameIndex = nameIndex; + this.descriptorIndex = descriptorIndex; + attributes = new ArrayList(1); // Usually 0 or 1? + } + + + /** + * Adds the specified attribute to this field. + * + * @param info Information about the attribute. + */ + public void addAttribute(AttributeInfo info) { + attributes.add(info); + } + + + /** + * Returns the specified attribute. + * + * @param index The index of the attribute. + * @return The attribute. + */ + public AttributeInfo getAttribute(int index) { + return attributes.get(index); + } + + + /** + * Returns the number of attributes of this field. + * + * @return The number of attributes. + */ + public int getAttributeCount() { + return attributes.size(); + } + + + public String getConstantValueAsString() { + ConstantValue cv = getConstantValueAttributeInfo(); + return cv==null ? null : cv.getConstantValueAsString(); + } + + + /** + * Returns the {@link ConstantValue} attribute info for this field, if any. + * + * @return The ConstantValue attribute, or null + * if there isn't one. + */ + private ConstantValue getConstantValueAttributeInfo() { + for (int i=0; iFieldInfo structure from the specified input + * stream. + * + * @param cf The class file containing this field. + * @param in The input stream to read from. + * @return The field information read. + * @throws IOException If an IO error occurs. + */ + public static FieldInfo read(ClassFile cf, DataInputStream in) + throws IOException { + FieldInfo info = new FieldInfo(cf, in.readUnsignedShort(), + in.readUnsignedShort(), + in.readUnsignedShort()); + int attrCount = in.readUnsignedShort(); + for (int i=0; inull if it was known + * to be unimportant for our purposes. + * @throws IOException If an IO error occurs. + */ + private AttributeInfo readAttribute(DataInputStream in) throws IOException { + + AttributeInfo ai = null; + + int attributeNameIndex = in.readUnsignedShort(); + int attributeLength = in.readInt(); + + String attrName = cf.getUtf8ValueFromConstantPool(attributeNameIndex); + + if (CONSTANT_VALUE.equals(attrName)) { // 4.7.2 + int constantValueIndex = in.readUnsignedShort(); + ConstantValue cv = new ConstantValue(cf, constantValueIndex); + ai = cv; + } + + // Attributes common to all members, or unhandled attributes. + else { + ai = super.readAttribute(in, attrName, attributeLength); + } + + return ai; + + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/Frame.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/Frame.java new file mode 100644 index 00000000..09ae3491 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/classreader/Frame.java @@ -0,0 +1,117 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.classreader; + +import java.util.*; + +import org.fife.rsta.ac.bsh.classreader.attributes.Code; + + +/** + * A Frame contains information on a method being decompiled, + * similar to a Frame as defined in 3.6 of the JVM spec. + * + * @author Robert Futrell + * @version 1.0 + */ +public class Frame { + + private Stack operandStack; + private LocalVarInfo[] localVars; + + + /** + * Constructor. + * + * @param code The {@link Code} attribute being decompiled. + */ + public Frame(Code code) { + + operandStack = new Stack(); + + localVars = new LocalVarInfo[code.getMaxLocals()]; + int i = 0; + MethodInfo mi = code.getMethodInfo(); + + // Instance methods have an implicit first parameter of "this". + if (!mi.isStatic()) { + localVars[i++] = new LocalVarInfo("this", true); + } + + // Name the passed-in local vars by their types. longs and doubles + // take up two slots. + String[] paramTypes = mi.getParameterTypes(); + for (int param_i=0; param_i-1) { // Class types. + type = type.substring(type.lastIndexOf('.')+1); + } + String name = "localVar_" + type + "_" + param_i; + localVars[i] = new LocalVarInfo(name, true); + i++; + if ("long".equals(type) || "double".equals(type)) { + i++; // longs and doubles take up two slots. + } + } + + // NOTE: Other local vars will still be "null" here! We need to + // infer their types from their usage during disassembly/decompilation. + System.out.println("NOTE: " + (localVars.length-i) + " unknown localVars slots"); + + } + + + public LocalVarInfo getLocalVar(int index, String defaultType) { + LocalVarInfo var = localVars[index]; + if (var==null) { + String name = "localVar_" + defaultType + "_" + index; + var = new LocalVarInfo(name, false); + localVars[index] = var; + } + else { + var.alreadyDeclared = true; // May be redundant + } + return var; + } + + + public String pop() { + return operandStack.pop(); + } + + + public void push(String value) { + operandStack.push(value); + } + + + public static class LocalVarInfo { + + private String value; + private boolean alreadyDeclared; + + public LocalVarInfo(String value, boolean alreadyDeclared) { + this.value = value; + this.alreadyDeclared = alreadyDeclared; + } + + public String getValue() { + return value; + } + + public boolean isAlreadyDeclared() { + return alreadyDeclared; + } + + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/MemberInfo.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/MemberInfo.java new file mode 100644 index 00000000..14896f81 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/classreader/MemberInfo.java @@ -0,0 +1,188 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.classreader; + +import java.io.DataInputStream; +import java.io.IOException; + +import org.fife.rsta.ac.bsh.classreader.attributes.AttributeInfo; +import org.fife.rsta.ac.bsh.classreader.attributes.Signature; + + +/** + * Base class for information about members (fields and methods). + * + * @author Robert Futrell + * @version 1.0 + * @see FieldInfo + * @see MethodInfo + */ +public abstract class MemberInfo { + + /** + * The class file in which this method is defined. + */ + protected ClassFile cf; + + /** + * A mask of flags used to denote access permission to and properties of + * this method. + */ + private int accessFlags; // u2 + + /** + * Whether this member is deprecated. + */ + private boolean deprecated; + + /** + * Attribute marking a member as deprecated. + */ + public static final String DEPRECATED = "Deprecated"; + + /** + * Attribute containing index of the member's signature. + */ + public static final String SIGNATURE = "Signature"; + + /** + * Attribute containing runtime-visible annotations. + */ + public static final String RUNTIME_VISIBLE_ANNOTATIONS = "RuntimeVisibleAnnotations"; + + + /** + * Constructor. + * + * @param cf The class file defining this member. + */ + protected MemberInfo(ClassFile cf, int accessFlags) { + this.cf = cf; + this.accessFlags = accessFlags; + } + + + /** + * Returns the access flags for this field. + * + * @return The access flags, as a bit field. + * @see AccessFlags + */ + public int getAccessFlags() { + return accessFlags; + } + + + /** + * Returns the parent class file. + * + * @return The parent class file. + */ + public ClassFile getClassFile() { + return cf; + } + + + /** + * Returns the name of this member. + * + * @return The name of this member. + */ + public abstract String getName(); + + + /** + * Returns whether this member is deprecated. + * + * @return Whether this member is deprecated. + */ + public boolean isDeprecated() { + return deprecated; + } + + + /** + * Returns the descriptor of this member. + * + * @return The descriptor of this member. + */ + public abstract String getDescriptor(); + + + /** + * Returns whether this member is final. + * + * @return Whether this member is final. + */ + public boolean isFinal() { + return (getAccessFlags()&AccessFlags.ACC_FINAL)>0; + } + + + /** + * Returns whether this member is static. + * + * @return Whether this member is static. + */ + public boolean isStatic() { + return (getAccessFlags()&AccessFlags.ACC_STATIC)>0; + } + + + /** + * Reads attributes common to all members. If the specified attribute is + * not common to members, the attribute returned is an "unsupported" + * attribute. + * + * @param in + * @param attrName + * @param attrLength + * @return The attribute, or null if it was purposely skipped + * for some reason (known to be useless for our purposes, etc.). + * @throws IOException + */ + protected AttributeInfo readAttribute(DataInputStream in, String attrName, + int attrLength) throws IOException { + + AttributeInfo ai = null; + + if (DEPRECATED.equals(attrName)) { // 4.7.10 + // No need to read anything else, attributeLength==0 + deprecated = true; + } + + else if (SIGNATURE.equals(attrName)) { // 4.8.8 + //System.err.println(">>> " + attributeLength); + int signatureIndex = in.readUnsignedShort(); + String typeSig = cf.getUtf8ValueFromConstantPool(signatureIndex); + ai = new Signature(cf, typeSig); + } + + else if (RUNTIME_VISIBLE_ANNOTATIONS.equals(attrName)) { // 4.8.15 + //String name = getClassFile().getClassName(false) + "." + getName(); + //System.out.println(name + ": Attribute " + attrName + " not supported"); + Util.skipBytes(in, attrLength); + //ai = null; + } + + else { + //String name = getClassFile().getClassName(false) + "." + getName(); + //System.out.println(name + ": Unsupported attribute: " + attrName); + ai = AttributeInfo.readUnsupportedAttribute(cf, in, attrName, + attrLength); + } + + return ai; + + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/MethodInfo.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/MethodInfo.java new file mode 100644 index 00000000..9bebc73b --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/classreader/MethodInfo.java @@ -0,0 +1,721 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.classreader; + +import org.fife.rsta.ac.bsh.classreader.attributes.Exceptions; +import org.fife.rsta.ac.bsh.classreader.attributes.Signature; +import org.fife.rsta.ac.bsh.classreader.attributes.Code; +import org.fife.rsta.ac.bsh.classreader.attributes.AttributeInfo; +import java.io.*; +import java.util.*; + + + +/** + * Implementation of the "method_info" structure as defined in + * the JVM specification. + * + * @author Robert Futrell + * @version 1.0 + */ +public class MethodInfo extends MemberInfo implements AccessFlags { + + /** + * An index into the constant pool of a {@link ConstantUtf8Info} structure + * representing either one of the special method names ( + * "<init>" or "<clinit>") or a + * valid method name in the Java programming language, stored as a simple + * name. + */ + private int nameIndex; // u2 + + /** + * An index into the constant pool of a {@link ConstantUtf8Info} structure + * representing a valid method descriptor. + */ + private int descriptorIndex; // u2 + + /** + * The Signature attribute, or null if there + * isn't one for this method. + */ + private Signature signatureAttr; + + /** + * The Code attribute, or null if this method + * is abstract or native. + */ + private Code codeAttr; + + /** + * All attributes of this method that aren't explicitly covered by the + * private members {@link #signatureAttr} and {@link #codeAttr}. + */ + private List attributes; + + /** + * The type of all parameters to this method. Note that this cache will + * be short-lived, as classes that take type parameters will pass their + * type arguments down to individual MethodInfos when doing + * completions, to ensure types are as correct as possible. + */ + private String[] paramTypes; + + /** + * Cached return type. + */ + private String returnType; + + /** + * Cached string representing the name and parameters for this method. + */ + private String nameAndParameters; + + /** + * Used in class files to denote constructors. + */ + private static final String SPECIAL_NAME_CONSTRUCTOR = ""; + + public static final String CODE = "Code"; + public static final String EXCEPTIONS = "Exceptions"; + + + /** + * Constructor. + * + * @param cf The class file defining this method. + */ + public MethodInfo(ClassFile cf, int accessFlags, int nameIndex, + int descriptorIndex) { + super(cf, accessFlags); + this.nameIndex = nameIndex; + this.descriptorIndex = descriptorIndex; + attributes = new ArrayList(1); // Usually only 0 or 1? + } + + + /** + * Adds the specified attribute to this field. + * + * @param info Information about the attribute. + */ + private void addAttribute(AttributeInfo info) { + attributes.add(info); + } + + + private void appendParamDescriptors(StringBuilder sb) { + + String[] paramTypes = getParameterTypes(); + for (int i=0; iMethodInfo to be used for code completion for instances + * of the same class initialized with different type arguments.

    + * + * Note that if this method does not have parameterized arguments or + * return type, calling this method won't affect its behavior. + */ + void clearParamTypeInfo() { + paramTypes = null; + returnType = null; + } + + + /** + * Creates and returns an array of types of all parameters of this + * method. If this method takes any generic type arguments, these + * types are grabbed from the parent ClassFile instance, + * whose type argument values should have been initialized via + * {@link ClassFile#setTypeParamsToTypeArgs(Map)}. + * + * @return The array of parameter types. + * @see #createParamTypesFromDescriptor() + * @see #createParamTypesFromTypeSignature() + */ + private String[] createParamTypes() { + String[] types = createParamTypesFromTypeSignature(); + if (types==null) { + types = createParamTypesFromDescriptor(true); + } + return types; + } + + + /** + * Creates an array of types of each parameter by looking at the method's + * descriptor field. This technique should work with Java 1.0+, but won't + * pick up on generic types added in Java 5. + * + * @return The parameter types. + * @see #createParamTypesFromTypeSignature() + */ + private String[] createParamTypesFromDescriptor(boolean qualified) { + + String descriptor = getDescriptor(); + int rparen = descriptor.indexOf(')'); + String paramDescriptors = descriptor.substring(1, rparen); + //String returnDescriptor = descriptor.substring(rparen+1); + + List paramTypeList = new ArrayList(); + String type = null; + + while (paramDescriptors.length()>0) { + + // Can't do lastIndexOf() as there may be > 1 array parameter + // in the descriptors. + // int braceCount = paramDescriptors.lastIndexOf('[') + 1; + int braceCount = -1; + while (paramDescriptors.charAt(++braceCount) == '['); + int pos = braceCount; + + switch (paramDescriptors.charAt(pos)) { + + // BaseType + case 'B': + type = "byte"; + pos++; + break; + case 'C': + type = "char"; + pos++; + break; + case 'D': + type = "double"; + pos++; + break; + case 'F': + type = "float"; + pos++; + break; + case 'I': + type = "int"; + pos++; + break; + case 'J': + type = "long"; + pos++; + break; + case 'S': + type = "short"; + pos++; + break; + case 'Z': + type = "boolean"; + pos++; + break; + + // ObjectType + case 'L': + String clazz = paramDescriptors.substring(pos + 1, + paramDescriptors.indexOf(';')); + type = qualified ? clazz.replace('/', '.') : clazz.substring(clazz.lastIndexOf('/')+1); + pos += clazz.length() + 2; // "+2" for the 'L' & semicolon + break; + + // Invalid method descriptor + default: + String temp = "INVALID_TYPE_" + paramDescriptors; + type = temp; + pos += paramDescriptors.length(); + break; + + } + + for (int i = 0; i < braceCount; i++) { + type += "[]"; + } + paramTypeList.add(type); + + paramDescriptors = paramDescriptors.substring(pos); + + } + + String[] types = new String[paramTypeList.size()]; + types = paramTypeList.toArray(types); + return types; + + } + + + /** + * Creates an array of types of each parameter by looking at the method's + * Signature attribute, and querying the parent + * ClassFile instance for any type argument values. This + * attribute was introduced in Java 5, and is the only way to detect + * generic parameters. + * + * @return The parameter types. + * @see #createParamTypesFromDescriptor() + */ + private String[] createParamTypesFromTypeSignature() { + + String[] params = null; + + if (signatureAttr!=null) { + List paramTypes = signatureAttr. + getMethodParamTypes(this, cf, false); + if (paramTypes!=null) { + params = new String[paramTypes.size()]; + params = paramTypes.toArray(params); + } + } + + return params; + + } + + + /** + * Returns the specified attribute. + * + * @param index The index of the attribute. + * @return The attribute. + */ + public AttributeInfo getAttribute(int index) { + return attributes.get(index); + } + + + /** + * Returns the number of attributes of this field. + * + * @return The number of attributes. + */ + public int getAttributeCount() { + return attributes.size(); + } + + + /** + * {@inheritDoc} + */ + @Override + public String getDescriptor() { + return cf.getUtf8ValueFromConstantPool(descriptorIndex); + } + + + /** + * {@inheritDoc} + */ + @Override + public String getName() { + String name = cf.getUtf8ValueFromConstantPool(nameIndex); + if (SPECIAL_NAME_CONSTRUCTOR.equals(name)) { + name = cf.getClassName(false); + } + return name; + } + + + /** + * Returns the name and parameters of this method, in the form + * performAction(String, int, Runnable). + * + * @return The name and parameters of this method. + */ + public String getNameAndParameters() { + + if (nameAndParameters==null) { + + StringBuilder sb = new StringBuilder(getName()); + + sb.append('('); + int paramCount = getParameterCount(); + for (int i=0; inull + * is returned. + * + * @param index The index of the parameter. + * @return The name of the parameter, or null. + */ + public String getParameterName(int index) { + if (index>=0 && index-1) { + type = type.substring(dot+1); + } + } + return type; + } + + + /** + * Returns an array if strings representing the types of all parameters + * to this method. If this method takes no parameters, a zero-length + * array is returned. + * + * @return The array. These types will likely be fully qualified. + * @see #getParameterCount() + * @see #getParameterType(int, boolean) + */ + public String[] getParameterTypes() { + if (paramTypes==null) { + paramTypes = createParamTypes(); + } + return paramTypes.clone(); + } + + /** + * Returns the return type of this method. + * + * @return The return type of this method. + */ + public String getReturnTypeString(boolean fullyQualified) { + if (returnType==null) { + returnType = getReturnTypeStringFromTypeSignature(fullyQualified); + if (returnType==null) { + returnType = getReturnTypeStringFromDescriptor(fullyQualified); + } + } + if(!fullyQualified) + { + if(returnType != null && returnType.indexOf(".") > -1) { + return returnType.substring(returnType.lastIndexOf(".") +1, returnType.length()); + } + } + return returnType; + } + + + /** + * Returns the return type of this method, as determined by a snippet + * of the method descriptor. This should work with all class files + * created in Java 1.0+, but won't discover the generic types added in + * Java 5. + * + * @return The return type of this method. + * @see #getReturnTypeStringFromTypeSignature() + */ + /* + * TODO: This is identical to FieldInfo.getTypeString(), except for the + * 'V' case. It is also very similar to #getParameterTypes(). Try + * to refactor common code from these methods. + */ + private String getReturnTypeStringFromDescriptor(boolean qualified) { + + String descriptor = getDescriptor(); + int rparen = descriptor.indexOf(')'); + descriptor = descriptor.substring(rparen+1); // return type desc. + StringBuilder sb = new StringBuilder(); + + int braceCount = descriptor.lastIndexOf('[') + 1; + + switch (descriptor.charAt(braceCount)) { + + // BaseType + case 'B': + sb.append("byte"); + break; + case 'C': + sb.append("char"); + break; + case 'D': + sb.append("double"); + break; + case 'F': + sb.append("float"); + break; + case 'I': + sb.append("int"); + break; + case 'J': + sb.append("long"); + break; + case 'S': + sb.append("short"); + break; + case 'Z': + sb.append("boolean"); + break; + case 'V': + sb.append("void"); + break; + + // ObjectType + case 'L': + String clazz = descriptor.substring(braceCount+1, descriptor.length()-1); + clazz = qualified ? clazz.replace('/', '.') : clazz.substring(clazz.lastIndexOf('/')+1); + sb.append(clazz); + break; + + // Invalid field descriptor + default: + sb.append("UNSUPPORTED_TYPE_").append(descriptor); + break; + + } + + for (int i=0; iSignature attribute that was added in Java 5. This allows + * us to check for generic types. + * + * @return The return type of this method. + * @see #getReturnTypeStringFromDescriptor() + */ + private String getReturnTypeStringFromTypeSignature(boolean qualified) { + String retType = null; + if (signatureAttr!=null) { + retType = signatureAttr.getMethodReturnType(this, cf, qualified); + } + + return retType; + + } + + + /** + * Returns the signature of this method, as determined from its method + * descriptor. + * + * @return The signature of this method. + */ + public String getSignature() { + + StringBuilder sb = new StringBuilder(); + + // Return type. + if (!isConstructor()) { // Don't print "void" return type. + sb.append(getReturnTypeString(false)); + sb.append(' '); + } + + // Method name and param list. + sb.append(getName()); + sb.append('('); + appendParamDescriptors(sb); + sb.append(')'); + + // "throws" clause. + for (AttributeInfo ai : attributes) { + if (ai instanceof Exceptions) { // At most 1 Exceptions attribute + sb.append(" throws "); + Exceptions ex = (Exceptions)ai; + for (int j=0; j0; + } + + + /** + * Returns whether this method is a constructor. + * + * @return Whether this method is a constructor. + */ + public boolean isConstructor() { + String name = cf.getUtf8ValueFromConstantPool(nameIndex); + return SPECIAL_NAME_CONSTRUCTOR.equals(name); + } + + + /** + * Returns whether this method is native. + * + * @return Whether this method is native. + */ + public boolean isNative() { + return (getAccessFlags()&ACC_NATIVE)>0; + } + + + /** + * Returns whether this method is static. + * + * @return Whether this method is static. + */ + @Override + public boolean isStatic() { + return (getAccessFlags()&ACC_STATIC)>0; + } + + + /** + * Reads a MethodInfo from an input stream. + * + * @param cf The class file defining the method. + * @param in The input stream to read from. + * @return The method information read. + * @throws IOException If an IO error occurs. + */ + public static MethodInfo read(ClassFile cf, DataInputStream in) + throws IOException { + int accessFlags = in.readUnsignedShort(); + int nameIndex = in.readUnsignedShort(); + int descriptorIndex = in.readUnsignedShort(); + MethodInfo mi = new MethodInfo(cf, accessFlags, nameIndex, + descriptorIndex); + int attrCount = in.readUnsignedShort(); + for (int j=0; jnull if it was known + * to be unimportant for our purposes. + * @throws IOException If an IO error occurs. + */ + private AttributeInfo readAttribute(DataInputStream in) throws IOException { + + AttributeInfo ai = null; + + int attributeNameIndex = in.readUnsignedShort(); + int attributeLength = in.readInt(); + + String attrName = cf.getUtf8ValueFromConstantPool(attributeNameIndex); + + if (CODE.equals(attrName)) { // 4.7.3 + ai = Code.read(this, in); + } + + else if (EXCEPTIONS.equals(attrName)) { // 4.7.4 + int exceptionCount = in.readUnsignedShort(); + int[] exceptionIndexTable = null; + if (exceptionCount>0) { + exceptionIndexTable = new int[exceptionCount]; + for (int i=0; i0; + } + + + /** + * Returns whether an object has protected scope. + * + * @return Whether an object has protected scope. + * @see #isDefault(int) + * @see #isPrivate(int) + * @see #isPublic(int) + */ + public static boolean isProtected(int accessFlags) { + return (accessFlags&ACC_PROTECTED)>0; + } + + + /** + * Returns whether an object has public scope. + * + * @return Whether an object has public scope. + * @see #isDefault(int) + * @see #isPrivate(int) + * @see #isPublic(int) + */ + public static boolean isPublic(int accessFlags) { + return (accessFlags&ACC_PUBLIC)>0; + } + + + /** + * Fully skips a given number of bytes in an input stream. + * + * @param in The input stream. + * @param count The number of bytes to skip. + * @throws IOException If an IO error occurs. + */ + public static void skipBytes(DataInputStream in, int count) + throws IOException { + int skipped = 0; + while (skippedin, + * in bytes. + * @return The attribute. + * @throws IOException If an IO error occurs. + */ + public static UnsupportedAttribute readUnsupportedAttribute(ClassFile cf, + DataInputStream in, String attrName, + int attrLength) throws IOException { + /* + int[] info = new int[attrLength]; + for (int i=0; iCode attribute contains the + * JVM instructions and auxiliary information for a single method, instance + * initialization method, or class or interface initialization method. Every + * JVM implementation must recognize Code attributes. If the + * method is either native or abstract, its + * MethodInfo structure must not have a Code + * attribute. Otherwise, its MethodInfo structure must have + * exactly one Code attribute. + * + * @author Robert Futrell + * @version 1.0 + */ +public class Code extends AttributeInfo { + + /** + * The parent method. + */ + private MethodInfo mi; + + /** + * The maximum depth of the operand stack of this method at any point + * during its execution. + */ + private int maxStack; + + /** + * The number of local variables in the local variable array allocated + * upon invocation of this method, including the local variables used to + * pass parameters to the method on invocation.

    + * + * The greatest local variable index for a value of type long + * or double is maxLocals-2. The greatest local + * variable index for a value of any other type is maxLocals-1. + */ + private int maxLocals; + +// /** +// * The actual bytes of JVM code that implement the method. This must have +// * length greater than zero. +// */ +// private int[] code; + + /** + * The size of the method's code, in bytes. + */ + private int codeLength; + + /** + * The exception handlers in the code array. The order of + * the handlers in this table is significant. + */ + private ExceptionTableEntry[] exceptionTable; + + /** + * The names of parameters to the parent method, if debugging was enabled + * during compilation. + * @see #LOCAL_VARIABLE_TABLE + */ + private String[] paramNames; + + /** + * Attributes of this Code attribute. + */ + private List attributes; + + private static final String LINE_NUMBER_TABLE = "LineNumberTable"; + private static final String LOCAL_VARIABLE_TABLE = "LocalVariableTable"; + private static final String LOCAL_VARIABLE_TYPE_TABLE = "LocalVariableTypeTable"; + private static final String STACK_MAP_TABLE = "StackMapTable"; + + + /** + * Constructor. + * + * @param mi Information on the parent method. + */ + public Code(MethodInfo mi) { + super(mi.getClassFile()); + this.mi = mi; + } + + +// /** +// * Returns the code byte at the specified offset. +// * +// * @param offset The offset. +// * @return The byte. +// */ +// public int getByte(int offset) { +// return code[offset]; +// } + + + /** + * Returns the length of the code array, in bytes. + * + * @return The length of the code array. + */ + public int getCodeLength() { + return codeLength;//code.length; + } + + + /** + * Returns the number of local variables in the local variable array + * allocated upon invocation of this method, including the local variables + * used to pass parameters to the method on invocation.

    + * + * The greatest local variable index for a value of type long + * or double is maxLocals-2. The greatest local + * variable index for a value of any other type is maxLocals-1. + * + * @return the maximum size of the local variable array. + */ + public int getMaxLocals() { + return maxLocals; + } + + + /** + * Returns the maximum depth of the operand stack of this method at any + * point during its execution. + */ + public int getMaxStack() { + return maxStack; + } + + + /** + * Returns the method containing this code. + * + * @return The method containing this code. + */ + public MethodInfo getMethodInfo() { + return mi; + } + + + /** + * If debugging was enabled during compilation, this method returns the + * name of the given parameter to this method. Otherwise, null + * is returned. + * + * @param index The index of the parameter. + * @return The name of the parameter, or null. + */ + public String getParameterName(int index) { + return paramNames==null ? null : paramNames[index]; + } + + + /** + * Reads a Code attribute from an input stream. + * + * @param mi The parent method. + * @param in The input stream. + * @return The Code attribute. + * @throws IOException If an IO error occurs. + */ + public static Code read(MethodInfo mi, DataInputStream in) + throws IOException { + + Code code = new Code(mi); + code.maxStack = in.readUnsignedShort(); + code.maxLocals = in.readUnsignedShort(); + code.codeLength = in.readInt(); + Util.skipBytes(in, code.codeLength); + + int exceptionTableLength = in.readUnsignedShort(); + if (exceptionTableLength>0) { + code.exceptionTable = new ExceptionTableEntry[exceptionTableLength]; + for (int i=0; i0) { + code.attributes = new ArrayList(1); // Usually 1 or 2 + for (int i=0; iCode attribute from an input + * stream. + * + * @param in The input stream to read from. + * @return The attribute read. + * @throws IOException If an IO error occurs. + */ + private AttributeInfo readAttribute(DataInputStream in) throws IOException { + + AttributeInfo ai = null; + ClassFile cf = mi.getClassFile(); + + int attributeNameIndex = in.readUnsignedShort(); + int attributeLength = in.readInt(); + + String attrName = cf.getUtf8ValueFromConstantPool(attributeNameIndex); + + // The line number table is more useful to a debugger than to us. + if (LINE_NUMBER_TABLE.equals(attrName)) { // 4.7.12 + //String name = mi.getName(true) + "."; + //System.out.println(name + ": Attribute " + attrName + " currently ignored"); + Util.skipBytes(in, attributeLength); + //ai = null; + } + + // Describes a local variable during execution of this code. We only + // use it to grab the names of method parameters. + else if (LOCAL_VARIABLE_TABLE.equals(attrName)) { // 4.7.13 + + // If this attribute is defined, then this class was compiled with + // debugging enabled! We can grab the names of the method + // parameters, to make code completion a little nicer. Note that + // we only grab the names of parameters, not all local variables, + // for speed and space. + + int paramCount = mi.getParameterCount(); + paramNames = new String[paramCount]; + boolean isStatic = mi.isStatic(); + + int localVariableTableLength = in.readUnsignedShort(); + for (int i=0; i=0 && adjustedIndexConstantValue" attribute, as defined by 4.7.2 of the + * JVM specification. + * + * @author Robert Futrell + * @version 1.0 + */ +public class ConstantValue extends AttributeInfo { + + /** + * An index into the constant pool that gives the constant value + * represented by this attribute. + */ + private int constantValueIndex; // u2 + + + /** + * CConstructor. + * + * @param cf The class file. + * @param constantValueIndex The index into the constant pool that gives + * the constant value represented by this attribute. + */ + public ConstantValue(ClassFile cf, int constantValueIndex) { + super(cf); + this.constantValueIndex = constantValueIndex; + } + + + /** + * Returns the index into the constant pool that gives the constant value + * represented by this attribute. + * + * @return The index. + */ + public int getConstantValueIndex() { + return constantValueIndex; + } + + + /** + * Returns the constant's value, as a string. + * + * @return The constant's value, as a string. + */ + public String getConstantValueAsString() { + + ClassFile cf = getClassFile(); + ConstantPoolInfo cpi = cf.getConstantPoolInfo(getConstantValueIndex()); + + if (cpi instanceof ConstantDoubleInfo) { + ConstantDoubleInfo cdi = (ConstantDoubleInfo)cpi; + double value = cdi.getDoubleValue(); + return Double.toString(value); + } + else if (cpi instanceof ConstantFloatInfo) { + ConstantFloatInfo cfi = (ConstantFloatInfo)cpi; + float value = cfi.getFloatValue(); + return Float.toString(value); + } + else if (cpi instanceof ConstantIntegerInfo) { + ConstantIntegerInfo cii = (ConstantIntegerInfo)cpi; + int value = cii.getIntValue(); + return Integer.toString(value); + } + else if (cpi instanceof ConstantLongInfo) { + ConstantLongInfo cli = (ConstantLongInfo)cpi; + long value = cli.getLongValue(); + return Long.toString(value); + } + else if (cpi instanceof ConstantStringInfo) { + ConstantStringInfo csi = (ConstantStringInfo)cpi; + return csi.getStringValue(); + } + else { + return "INVALID_CONSTANT_TYPE_" + cpi.toString(); + } + + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/attributes/Exceptions.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/attributes/Exceptions.java new file mode 100644 index 00000000..f88ceb84 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/classreader/attributes/Exceptions.java @@ -0,0 +1,88 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.classreader.attributes; + +import org.fife.rsta.ac.bsh.classreader.constantpool.ConstantClassInfo; +import org.fife.rsta.ac.bsh.classreader.constantpool.ConstantPoolInfo; +import org.fife.rsta.ac.bsh.classreader.ClassFile; +import org.fife.rsta.ac.bsh.classreader.MethodInfo; + + +/** + * Implementation of the "Exceptions" attribute found in + * {@link MethodInfo}s. + * + * @author Robert Futrell + * @version 1.0 + */ +public class Exceptions extends AttributeInfo { + + /** + * The method this attribute is describing. + */ + private MethodInfo mi; + + /** + * Indices into the constant pool of {@link ConstantClassInfo}s, each + * representing a class type that this method is declared to throw. + */ + private int[] exceptionIndexTable; + + + /** + * Constructor. + * + * @param mi The method this attribute is describing. + */ + public Exceptions(MethodInfo mi, int[] exceptionIndexTable) { + super(mi.getClassFile()); + this.exceptionIndexTable = exceptionIndexTable; + } + + + /** + * Returns the fully-qualified name of the specified exception. + * + * @param index The index of the exception whose name to retrieve. + * @return The name of the exception. + */ + public String getException(int index) { + ClassFile cf = getClassFile(); + ConstantPoolInfo cpi = cf.getConstantPoolInfo( + exceptionIndexTable[index]); + ConstantClassInfo cci = (ConstantClassInfo)cpi; + int nameIndex = cci.getNameIndex(); + String name = cf.getUtf8ValueFromConstantPool(nameIndex); + return name.replace('/', '.'); + } + + + /** + * Returns the number of exceptions this attribute knows about. + * + * @return The number of exceptions. + */ + public int getExceptionCount() { + return exceptionIndexTable==null ? 0 : exceptionIndexTable.length; + } + + + /** + * Returns information about the method this attribute is describing. + * + * @return The method information. + */ + public MethodInfo getMethodInfo() { + return mi; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/attributes/Signature.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/attributes/Signature.java new file mode 100644 index 00000000..8c711ac0 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/classreader/attributes/Signature.java @@ -0,0 +1,424 @@ +/* + * 01/16/2011 + * + * Copyright (C) 2011 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.classreader.attributes; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.fife.rsta.ac.bsh.classreader.ClassFile; +import org.fife.rsta.ac.bsh.classreader.MethodInfo; + + +/** + * The Signature attribute is an optional fixed-length attribute in the + * attribute table of the ClassFile, field_info and method_info + * structures.

    + * WARNING: This code is a complete mess. + * + * @author Robert Futrell + * @version 1.0 + */ +public class Signature extends AttributeInfo { + + private String signature; + + + public Signature(ClassFile cf, String signature) { + super(cf); + this.signature = signature; + } + + + public List getClassParamTypes() { + + List types = null; + + if (signature!=null && signature.startsWith("<")) { + + types = new ArrayList(1); // Usually a small number + int afterMatchingGT = skipLtGt(signature, 1); + + // We're assuming we don't come across corrupt signatures... + + String temp = signature.substring(1, afterMatchingGT-1); + int offs = 0; + int colon = temp.indexOf(':', offs); + while (offs-1) { + String ident = temp.substring(offs, colon); + int colonCount = 1; + char ch = temp.charAt(colon+colonCount); + if (ch==':') { // sometimes, there is another ':' + colonCount++; + ch = temp.charAt(colon+colonCount); + } + if (ch=='L') { // A ClassTypeSignature + int semicolon = temp.indexOf(';', colon+colonCount+1); + if (semicolon>-1) { + //String type = temp.substring(colon+2, semicolon); + // TODO: ... + types.add(ident); + offs = semicolon + 1; + colon = temp.indexOf(':', offs); + } + else { + System.err.println("WARN: Can't parse signature (1): " + signature); + break; + } + } + else { + System.err.println("WARN: Can't parse signature (2): " + signature); + break; + } + } + } + + return types; + + } + + + private int skipLtGt(String str, int start) { + + int ltCount = 1; + int offs = start; + + while (offs0) { + char ch = str.charAt(offs++); + switch (ch) { + case '<': + ltCount++; + break; + case '>': + ltCount--; + break; + } + } + + return offs; + + } + + + public List getMethodParamTypes(MethodInfo mi, ClassFile cf, + boolean qualified) { + + List paramTypeList = null; + String signature = this.signature; // Since we modify it + + if (signature!=null) { + + paramTypeList = new ArrayList(); + + // Handle "<...>", which essentially defines extra type args + Map additionalTypeArgs = null; + if (signature.charAt(0)=='<') { + int afterMatchingGT = skipLtGt(signature, 1); + String typeParams = signature.substring(1, afterMatchingGT-1); + additionalTypeArgs = parseAdditionalTypeArgs(typeParams); + signature = signature.substring(afterMatchingGT); + } + + if (signature.charAt(0)=='(') { + + int rparen = signature.indexOf(')', 1); + String paramDescriptors = signature.substring(1, rparen); + ParamDescriptorResult res = new ParamDescriptorResult(); + + while (paramDescriptors.length()>0) { + parseParamDescriptor(paramDescriptors, cf, additionalTypeArgs, + mi, "Error parsing method signature for ", res, qualified); + paramTypeList.add(res.type); + if(paramDescriptors.length()>res.pos) { + paramDescriptors = paramDescriptors.substring(res.pos); + } else { + break; + } + } + + } + + else { + System.out.println("TODO: Unhandled method signature for " + + mi.getName() + ": " + signature); + } + + } + + return paramTypeList; + + } + + + public String getMethodReturnType(MethodInfo mi, ClassFile cf, boolean qualified) { + + String signature = this.signature; // Since we modify it + String sig = null; + + if (signature!=null) { + + // Handle "<...>", which essentially defines extra type args + Map additionalTypeArgs = null; + if (signature.charAt(0)=='<') { + int afterMatchingGT = skipLtGt(signature, 1); + String typeParams = signature.substring(1, afterMatchingGT-1); + additionalTypeArgs = parseAdditionalTypeArgs(typeParams); + signature = signature.substring(afterMatchingGT); + } + + if (signature.charAt(0)=='(') { + int rparen = signature.indexOf(')', 1); + if (rparen>-1 && rparen<T> T[] toArray(T[] a)", where the + * "T" type parameter is the type of an argument passed + * to it). + * @return The type argument, or null if the given type + * parameter isn't defined. + */ + private String getTypeArgument(String typeVar, ClassFile cf, + Map additionalTypeArgs) { + String type = cf.getTypeArgument(typeVar); + if (type==null && additionalTypeArgs!=null) { + //type = (String)additionalTypeArgs.get(typeVar); + type = typeVar; + } + return type; + } + + + private Map parseAdditionalTypeArgs(String typeParams) { + + Map additionalTypeArgs = new HashMap(); + int offs = 0; + int colon = typeParams.indexOf(':', offs); + + while (offs-1 && lt additionalTypeArgs, + MethodInfo mi, String errorDesc, + ParamDescriptorResult res, boolean qualified) { + + // Can't do lastIndexOf() as there may be > 1 array parameter + // in the descriptors. + // int braceCount = str.lastIndexOf('[') + 1; + int braceCount = -1; + while (str.charAt(++braceCount) == '['); + int pos = braceCount; + String type = null; + boolean extendingGenericType = false; + + switch (str.charAt(pos)) { + + // BaseType + case 'B': + type = "byte"; + pos++; + break; + case 'C': + type = "char"; + pos++; + break; + case 'D': + type = "double"; + pos++; + break; + case 'F': + type = "float"; + pos++; + break; + case 'I': + type = "int"; + pos++; + break; + case 'J': + type = "long"; + pos++; + break; + case 'S': + type = "short"; + pos++; + break; + case 'Z': + type = "boolean"; + pos++; + break; + + // ObjectType + case 'L': + int semicolon = str.indexOf(';', pos+1); + int lt = str.indexOf('<', pos+1); + if (lt>-1 && lt paramTypeList = new ArrayList(); + // Recursively parse type parameters of this parameter + while (paramDescriptors.length()>0) { + parseParamDescriptor(paramDescriptors, cf, additionalTypeArgs, + mi, "Error parsing method signature for ", res2, qualified); + paramTypeList.add(res2.type); + if(paramDescriptors.length()>res2.pos) { + paramDescriptors = paramDescriptors.substring(res2.pos); + } else { + break; + } + + } + StringBuilder sb = new StringBuilder(type).append('<'); + for (int i=0; i').toString(); + pos = offs+1;//semicolon + 1; Skip semicolon that came AFTER "<...>" + } + } + else { + String clazz = str.substring(pos + 1, semicolon); + //clazz = org.fife.rsta.ac.java.Util.replaceChar(clazz, '/', '.'); + //clazz = clazz.substring(clazz.lastIndexOf('/')+1); + clazz = qualified ? clazz.replace('/', '.') : clazz.substring(clazz.lastIndexOf('/')+1); + type = clazz; + pos += semicolon + 1; + } + break; + + case '+': // "super extends T" + extendingGenericType = true; + pos++; + // Fall through + + case 'T': // Generic type + semicolon = str.indexOf(';', pos+1); + String typeVar = str.substring(pos+1, semicolon); + type = getTypeArgument(typeVar, cf, additionalTypeArgs); + if (type==null) { + type = "UNKNOWN_GENERIC_TYPE_" + typeVar; + } + else if (extendingGenericType) { + type = "? extends " + type; + } + pos = semicolon + 1; + break; + + case '*': + type = "?"; + pos++; + break; + + // Invalid method descriptor + default: + String temp = "INVALID_TYPE_" + str; + type = temp; + pos += str.length(); + break; + + } + + for (int i = 0; i < braceCount; i++) { + type += "[]"; + } + + return res.set(type, pos); + + } + + + @Override + public String toString() { + return "[Signature: signature=" + getSignature() + "]"; + } + + + private static class ParamDescriptorResult { + + public String type; + public int pos; + + public ParamDescriptorResult set(String type, int pos) { + this.type = type; + this.pos = pos; + return this; + } + + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/attributes/SourceFile.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/attributes/SourceFile.java new file mode 100644 index 00000000..3b0a2592 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/classreader/attributes/SourceFile.java @@ -0,0 +1,73 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.classreader.attributes; + +import org.fife.rsta.ac.bsh.classreader.ClassFile; + + +/** + * The SourceFile attribute, an optional fixed-length attribute + * in the attributes table of a {@link ClassFile}. There can be no more than + * one SourceFile attribute for a given ClassFile. + * + * @author Robert Futrell + * @version 1.0 + */ +public class SourceFile extends AttributeInfo { + + /** + * Index into the constant pool of a {@link ConstantUtf8Info} structure + * representing the name of the source file from which this class file + * was compiled. + */ + private int sourceFileIndex; + + + /** + * Constructor. + * + * @param cf The class file. + * @param sourceFileIndex Index into the constant pool of a + * {@link ConstantUtf8Info} structure representing the source file + * name. + */ + public SourceFile(ClassFile cf, int sourceFileIndex) { + super(cf); + this.sourceFileIndex = sourceFileIndex; + } + + + /** + * Returns the name of the source file that was compiled to create this + * class file. + * + * @return The name of the source file. + */ + public String getSourceFileName() { + return getClassFile().getUtf8ValueFromConstantPool(sourceFileIndex); + } + + + /** + * Returns a string representation of this attribute. Useful for + * debugging. + * + * @return A string representation of this attribute. + */ + @Override + public String toString() { + return "[SourceFile: " + + "file=" + getSourceFileName() + + "]"; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/attributes/UnsupportedAttribute.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/attributes/UnsupportedAttribute.java new file mode 100644 index 00000000..1c4d5ba5 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/classreader/attributes/UnsupportedAttribute.java @@ -0,0 +1,65 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.classreader.attributes; + +import org.fife.rsta.ac.bsh.classreader.ClassFile; + + +/** + * An attribute that is unknown/unsupported by this decompiler. + * + * @author Robert Futrell + * @version 1.0 + */ +public class UnsupportedAttribute extends AttributeInfo { + + private String name; + //private int[] info; + + + /** + * Constructor. + * + * @param cf The class file. + */ + public UnsupportedAttribute(ClassFile cf, String name/*, int[] info*/) { + super(cf); + this.name = name; + //this.info = info; + } + +/* + public int[] getInfo() { + return info; + } +*/ + + @Override + public String getName() { + return name; + } + + + /** + * Returns a string representation of this attribute. Useful for + * debugging. + * + * @return A string representation of this attribute. + */ + @Override + public String toString() { + return "[UnsupportedAttribute: " + + "name=" + getName() + + "]"; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantClassInfo.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantClassInfo.java new file mode 100644 index 00000000..59ebc3b5 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantClassInfo.java @@ -0,0 +1,69 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.classreader.constantpool; + + +/** + * Represents a class or interface. + * + * @author Robert Futrell + * @version 1.0 + */ +public class ConstantClassInfo extends ConstantPoolInfo { + + /** + * An index into the constant_pool table. The entry at this index + * must be a CONSTANT_Utf8_info structure representing + * a valid, fully-qualified class or interface name encoded in internal + * form. + */ + private int nameIndex; + + + /** + * Constructor. + * + * @param nameIndex The index into the constant pool containing a + * {@link ConstantUtf8Info} representing the fully-qualified + * class or interface name, encoded in internal form. + */ + public ConstantClassInfo(int nameIndex) { + super(CONSTANT_Class); + this.nameIndex = nameIndex; + } + + + /** + * Returns the index into the constant pool table for a + * ConstantUtf8Info structure representing a valid, + * fully-qualified class or interface name, encoded in internal form. + * + * @return The index into the constant pool table. + */ + public int getNameIndex() { + return nameIndex; + } + + + /** + * Returns a string representation of this object. Useful for debugging. + * + * @return A string representation of this object. + */ + @Override + public String toString() { + return "[ConstantClassInfo: " + + "nameIndex=" + getNameIndex() + + "]"; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantDoubleInfo.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantDoubleInfo.java new file mode 100644 index 00000000..59d17748 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantDoubleInfo.java @@ -0,0 +1,73 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.classreader.constantpool; + + +/** + * Class corresponding to the CONSTANT_Double_info structure. + * + * @author Robert Futrell + * @version 1.0 + */ +public class ConstantDoubleInfo extends ConstantPoolInfo { + + private int highBytes; + private int lowBytes; + + + /** + * Constructor. + * + * @param highBytes + * @param lowBytes + */ + public ConstantDoubleInfo(int highBytes, int lowBytes) { + super(CONSTANT_Double); + this.highBytes = highBytes; + this.lowBytes = lowBytes; + } + + + /** + * Returns the double value represented by this constant. + * + * @return The double value. + */ + public double getDoubleValue() { + long bits = (((long)highBytes<<32)) + lowBytes; + return Double.longBitsToDouble(bits); + } + + + public int getHighBytes() { + return highBytes; + } + + + public int getLowBytes() { + return lowBytes; + } + + + /** + * Returns a string representation of this object. Useful for debugging. + * + * @return A string representation of this object. + */ + @Override + public String toString() { + return "[ConstantDoubleInfo: " + + "value=" + getDoubleValue() + + "]"; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantFieldrefInfo.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantFieldrefInfo.java new file mode 100644 index 00000000..5d15b84b --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantFieldrefInfo.java @@ -0,0 +1,64 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.classreader.constantpool; + + +/** + * Class corresponding to a CONSTANT_Fieldref_info structure. + * + * @author Robert Futrell + * @version 1.0 + */ +public class ConstantFieldrefInfo extends ConstantPoolInfo { + + private int classIndex; + + private int nameAndTypeIndex; + + + /** + * Constructor. + * + * @param classIndex + * @param nameAndTypeIndex + */ + public ConstantFieldrefInfo(int classIndex, int nameAndTypeIndex) { + super(CONSTANT_Fieldref); + this.classIndex = classIndex; + this.nameAndTypeIndex = nameAndTypeIndex; + } + + + public int getClassIndex() { + return classIndex; + } + + + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + + + /** + * Returns a string representation of this object. Useful for debugging. + * + * @return A string representation of this object. + */ + @Override + public String toString() { + return "[ConstantFieldrefInfo: " + + "classIndex=" + getClassIndex() + + "; nameAndTypeIndex=" + getNameAndTypeIndex() + + "]"; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantFloatInfo.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantFloatInfo.java new file mode 100644 index 00000000..22a71bcf --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantFloatInfo.java @@ -0,0 +1,64 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.classreader.constantpool; + + +/** + * Class corresponding to the CONSTANT_Float_info structure. + * + * @author Robert Futrell + * @version 1.0 + */ +public class ConstantFloatInfo extends ConstantPoolInfo { + + private int bytes; // u4 + + + /** + * Constructor. + * + * @param bytes + */ + public ConstantFloatInfo(int bytes) { + super(CONSTANT_Float); + this.bytes = bytes; + } + + + public long getBytes() { + return bytes; + } + + + /** + * Returns the float value represented. + * + * @return The float value. + */ + public float getFloatValue() { + return Float.intBitsToFloat(bytes); + } + + + /** + * Returns a string representation of this object. Useful for debugging. + * + * @return A string representation of this object. + */ + @Override + public String toString() { + return "[ConstantFloatInfo: " + + "value=" + getFloatValue() + + "]"; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantIntegerInfo.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantIntegerInfo.java new file mode 100644 index 00000000..0236218d --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantIntegerInfo.java @@ -0,0 +1,62 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.classreader.constantpool; + + +/** + * Class corresponding to the CONSTANT_Integer_info structure. + * + * @author Robert Futrell + * @version 1.0 + */ +public class ConstantIntegerInfo extends ConstantPoolInfo { + + private long bytes; // u4 + + + /** + * Constructor. + */ + public ConstantIntegerInfo(long bytes) { + super(CONSTANT_String); + this.bytes = bytes; + } + + + public long getBytes() { + return bytes; + } + + + /** + * Returns the intrepresented by this info. + * + * @return The int represented. + */ + public int getIntValue() { + return (int)bytes; + } + + + /** + * Returns a string representation of this object. Useful for debugging. + * + * @return A string representation of this object. + */ + @Override + public String toString() { + return "[ConstantIntegerInfo: " + + "bytes=" + getBytes() + + "]"; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantInterfaceMethodrefInfo.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantInterfaceMethodrefInfo.java new file mode 100644 index 00000000..59c4ae7c --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantInterfaceMethodrefInfo.java @@ -0,0 +1,66 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.classreader.constantpool; + + +/** + * Class corresponding to a CONSTANT_InterfaceMethodref_info + * structure. + * + * @author Robert Futrell + * @version 1.0 + */ +class ConstantInterfaceMethodrefInfo extends ConstantPoolInfo { + + + private int classIndex; + + private int nameAndTypeIndex; + + + /** + * Constructor. + * + * @param classIndex + * @param nameAndTypeIndex + */ + public ConstantInterfaceMethodrefInfo(int classIndex, int nameAndTypeIndex){ + super(CONSTANT_InterfaceMethodref); + this.classIndex = classIndex; + this.nameAndTypeIndex = nameAndTypeIndex; + } + + + public int getClassIndex() { + return classIndex; + } + + + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + + + /** + * Returns a string representation of this object. Useful for debugging. + * + * @return A string representation of this object. + */ + @Override + public String toString() { + return "[ConstantInterfaceMethodrefInfo: " + + "classIndex=" + getClassIndex() + + "; nameAndTypeIndex=" + getNameAndTypeIndex() + + "]"; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantInvokeDynamicInfo.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantInvokeDynamicInfo.java new file mode 100644 index 00000000..c0d89c0c --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantInvokeDynamicInfo.java @@ -0,0 +1,63 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.classreader.constantpool; + +/** + * Class representing a CONSTANT_InvokeDynamic_info structure. + * + * @author Robert Futrell + * @version 1.0 + */ +public class ConstantInvokeDynamicInfo extends ConstantPoolInfo { + + private int bootstrapMethodAttrIndex; + + private int nameAndTypeIndex; + + + /** + * Constructor. + * + * @param bootstrapMethodAttrIndex + * @param nameAndTypeIndex + */ + public ConstantInvokeDynamicInfo(int bootstrapMethodAttrIndex, int nameAndTypeIndex) { + super(CONSTANT_InvokeDynamic); + this.bootstrapMethodAttrIndex = bootstrapMethodAttrIndex; + this.nameAndTypeIndex = nameAndTypeIndex; + } + + + public int getBootstrapMethodAttrIndex() { + return bootstrapMethodAttrIndex; + } + + + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + + + /** + * Returns a string representation of this object. Useful for debugging. + * + * @return A string representation of this object. + */ + @Override + public String toString() { + return "[ConstantInvokeDynamicInfo: " + + "bootstrapMethodAttrIndex=" + getBootstrapMethodAttrIndex() + + "; nameAndTypeIndex=" + getNameAndTypeIndex() + + "]"; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantLongInfo.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantLongInfo.java new file mode 100644 index 00000000..30d189ff --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantLongInfo.java @@ -0,0 +1,67 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.classreader.constantpool; + + +/** + * Class corresponding to the CONSTANT_Long_info structure. + * + * @author Robert Futrell + * @version 1.0 + */ +public class ConstantLongInfo extends ConstantPoolInfo { + + private int highBytes; // u4 + private int lowBytes; // u4 + + + /** + * Constructor. + * + * @param highBytes + * @param lowBytes + */ + public ConstantLongInfo(int highBytes, int lowBytes) { + super(CONSTANT_Long); + this.highBytes = highBytes; + this.lowBytes = lowBytes; + } + + + public int getHighBytes() { + return highBytes; + } + + + public long getLongValue() { + return (((long)highBytes<<32)) + lowBytes; + } + + + public int getLowBytes() { + return lowBytes; + } + + + /** + * Returns a string representation of this object. Useful for debugging. + * + * @return A string representation of this object. + */ + @Override + public String toString() { + return "[ConstantLongInfo: " + + "value=" + getLongValue() + + "]"; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantMethodHandleInfo.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantMethodHandleInfo.java new file mode 100644 index 00000000..56cda546 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantMethodHandleInfo.java @@ -0,0 +1,62 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.classreader.constantpool; + +/** + * Class representing a CONSTANT_MethodHandle structure. + * + * @author Robert Futrell + * @version 1.0 + */ +public class ConstantMethodHandleInfo extends ConstantPoolInfo { + + private int referenceKind; + + private int referenceIndex; + + + /** + * Constructor. + * + * @param referenceKind + * @param referenceIndex + */ + public ConstantMethodHandleInfo(int referenceKind, int referenceIndex) { + super(CONSTANT_MethodHandle); + this.referenceKind = referenceKind; + this.referenceIndex = referenceIndex; + } + + + public int getReferenceKind() { + return referenceKind; + } + + public int getReferenceIndex() { + return referenceIndex; + } + + + /** + * Returns a string representation of this object. Useful for debugging. + * + * @return A string representation of this object. + */ + @Override + public String toString() { + return "[ConstantMethodHandleInfo: " + + "referenceKind=" + getReferenceKind() + + "; referenceIndex=" + getReferenceIndex() + + "]"; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantMethodTypeInfo.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantMethodTypeInfo.java new file mode 100644 index 00000000..aa4a17aa --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantMethodTypeInfo.java @@ -0,0 +1,52 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.classreader.constantpool; + +/** + * Class representing a CONSTANT_MethodType structure. + * + * @author Robert Futrell + * @version 1.0 + */ +public class ConstantMethodTypeInfo extends ConstantPoolInfo { + + private int descriptorIndex; + + /** + * Constructor. + * + * @param descriptorIndex + */ + public ConstantMethodTypeInfo(int descriptorIndex) { + super(CONSTANT_MethodType); + this.descriptorIndex = descriptorIndex; + } + + + public int getDescriptorIndex() { + return descriptorIndex; + } + + + /** + * Returns a string representation of this object. Useful for debugging. + * + * @return A string representation of this object. + */ + @Override + public String toString() { + return "[ConstantMethodTypeInfo: " + + "bootstrapMethodAttrIndex=" + getDescriptorIndex() + + "]"; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantMethodrefInfo.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantMethodrefInfo.java new file mode 100644 index 00000000..3eccab9a --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantMethodrefInfo.java @@ -0,0 +1,64 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.classreader.constantpool; + + +/** + * Class corresponding to a CONSTANT_Methodref_info structure. + * + * @author Robert Futrell + * @version 1.0 + */ +public class ConstantMethodrefInfo extends ConstantPoolInfo { + + private int classIndex; + + private int nameAndTypeIndex; + + + /** + * Constructor. + * + * @param classIndex + * @param nameAndTypeIndex + */ + public ConstantMethodrefInfo(int classIndex, int nameAndTypeIndex) { + super(CONSTANT_Methodref); + this.classIndex = classIndex; + this.nameAndTypeIndex = nameAndTypeIndex; + } + + + public int getClassIndex() { + return classIndex; + } + + + public int getNameAndTypeIndex() { + return nameAndTypeIndex; + } + + + /** + * Returns a string representation of this object. Useful for debugging. + * + * @return A string representation of this object. + */ + @Override + public String toString() { + return "[ConstantMethodrefInfo: " + + "classIndex=" + getClassIndex() + + "; nameAndTypeIndex=" + getNameAndTypeIndex() + + "]"; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantNameAndTypeInfo.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantNameAndTypeInfo.java new file mode 100644 index 00000000..893d3e79 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantNameAndTypeInfo.java @@ -0,0 +1,63 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.classreader.constantpool; + + +/** + * Class representing a CONSTANT_NameAndType_info structure. + * + * @author Robert Futrell + * @version 1.0 + */ +public class ConstantNameAndTypeInfo extends ConstantPoolInfo { + + private int nameIndex; + private int descriptorIndex; + + + /** + * Constructor. + * + * @param nameIndex + * @param descriptorIndex + */ + public ConstantNameAndTypeInfo(int nameIndex, int descriptorIndex) { + super(CONSTANT_NameAndType); + this.nameIndex = nameIndex; + this.descriptorIndex = descriptorIndex; + } + + + public int getDescriptorIndex() { + return descriptorIndex; + } + + + public int getNameIndex() { + return nameIndex; + } + + + /** + * Returns a string representation of this object. Useful for debugging. + * + * @return A string representation of this object. + */ + @Override + public String toString() { + return "[ConstantNameAndTypeInfo: " + + "descriptorIndex=" + getDescriptorIndex() + + "; nameIndex=" + getNameIndex() + + "]"; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantPoolInfo.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantPoolInfo.java new file mode 100644 index 00000000..63bfe8c5 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantPoolInfo.java @@ -0,0 +1,47 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.classreader.constantpool; + + +/** + * A ConstantPool table entry.

    + * + * See + * http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html#20080 + * for more information. + * + * @author Robert Futrell + * @version 1.0 + */ +public abstract class ConstantPoolInfo implements ConstantTypes { + + private int tag; + + + /** + * Constructor. + */ + public ConstantPoolInfo(int tag) { + this.tag = tag; + } + + + /** + * Returns the tag item for this structure. + * + * @return The tag item. + */ + public int getTag() { + return tag; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantPoolInfoFactory.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantPoolInfoFactory.java new file mode 100644 index 00000000..1865f16d --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantPoolInfoFactory.java @@ -0,0 +1,127 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.classreader.constantpool; + +import org.fife.rsta.ac.bsh.classreader.ClassFile; +import java.io.DataInputStream; +import java.io.IOException; + + + +public class ConstantPoolInfoFactory implements ConstantTypes { + + + /** + * Private constructor to prevent instantiation. + */ + private ConstantPoolInfoFactory() { + } + + + public static ConstantPoolInfo readConstantPoolInfo(ClassFile cf, + DataInputStream in) throws IOException { + + ConstantPoolInfo cpi = null; + int tag = in.read(); + + switch (tag) { + + case CONSTANT_Class: + int nameIndex = in.readUnsignedShort(); + cpi = new ConstantClassInfo(nameIndex); + break; + + case CONSTANT_Double: + int highBytes = in.readInt(); + int lowBytes = in.readInt(); + cpi = new ConstantDoubleInfo(highBytes, lowBytes); + break; + + case CONSTANT_Fieldref: + int classIndex = in.readUnsignedShort(); + int nameAndTypeIndex = in.readUnsignedShort(); + cpi = new ConstantFieldrefInfo(classIndex, nameAndTypeIndex); + break; + + case CONSTANT_Float: + int bytes = in.readInt(); + cpi = new ConstantFloatInfo(bytes); + break; + + case CONSTANT_Integer: + bytes = in.readInt(); + cpi = new ConstantIntegerInfo(bytes); + break; + + case CONSTANT_InterfaceMethodref: + classIndex = in.readUnsignedShort(); + nameAndTypeIndex = in.readUnsignedShort(); + cpi = new ConstantInterfaceMethodrefInfo(classIndex, nameAndTypeIndex); + break; + + case CONSTANT_Long: + highBytes = in.readInt(); + lowBytes = in.readInt(); + cpi = new ConstantLongInfo(highBytes, lowBytes); + break; + + case CONSTANT_Methodref: + classIndex = in.readUnsignedShort(); + nameAndTypeIndex = in.readUnsignedShort(); + cpi = new ConstantMethodrefInfo(classIndex, nameAndTypeIndex); + break; + + case CONSTANT_NameAndType: + nameIndex = in.readUnsignedShort(); + int descriptorIndex = in.readUnsignedShort(); + cpi = new ConstantNameAndTypeInfo(nameIndex, descriptorIndex); + break; + + case CONSTANT_String: + int stringIndex = in.readUnsignedShort(); + cpi = new ConstantStringInfo(cf, stringIndex); + break; + + case CONSTANT_Utf8: + int count = in.readUnsignedShort(); + byte[] byteArray = new byte[count]; + in.readFully(byteArray); + cpi = new ConstantUtf8Info(byteArray); + break; + + case CONSTANT_MethodHandle: + int referenceKind = in.read(); + int referenceIndex = in.readUnsignedShort(); + cpi = new ConstantMethodHandleInfo(referenceKind, referenceIndex); + break; + + case CONSTANT_MethodType: + descriptorIndex = in.readUnsignedShort(); + cpi = new ConstantMethodTypeInfo(descriptorIndex); + break; + + case CONSTANT_InvokeDynamic: + int bootstrapMethodAttrIndex = in.readUnsignedShort(); + nameAndTypeIndex = in.readUnsignedShort(); + cpi = new ConstantInvokeDynamicInfo(bootstrapMethodAttrIndex, nameAndTypeIndex); + break; + + default: + throw new IOException("Unknown tag for constant pool info: " + tag); + + } + + return cpi; + + } + + +} diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantStringInfo.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantStringInfo.java new file mode 100644 index 00000000..e80bbe8b --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantStringInfo.java @@ -0,0 +1,69 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.classreader.constantpool; + +import org.fife.rsta.ac.bsh.classreader.ClassFile; + + +/** + * Class corresponding to the CONSTANT_String_info structure. + * + * @author Robert Futrell + * @version 1.0 + */ +public class ConstantStringInfo extends ConstantPoolInfo { + + private ClassFile cf; + private int stringIndex; + + + /** + * Constructor. + * + * @param stringIndex + */ + public ConstantStringInfo(ClassFile cf, int stringIndex) { + super(CONSTANT_String); + this.cf = cf; + this.stringIndex = stringIndex; + } + + + public int getStringIndex() { + return stringIndex; + } + + + /** + * Returns the string represented by this constant. + * + * @return The string value represented. + */ + public String getStringValue() { + return '"' + cf.getUtf8ValueFromConstantPool(getStringIndex()) + '"'; + + } + + + /** + * Returns a string representation of this object. Useful for debugging. + * + * @return A string representation of this object. + */ + @Override + public String toString() { + return "[ConstantStringInfo: " + + "stringIndex=" + getStringIndex() + + "]"; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantTypes.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantTypes.java new file mode 100644 index 00000000..12dd687c --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantTypes.java @@ -0,0 +1,50 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.classreader.constantpool; + + +/** + * Constant types used by {@link ConstantPoolInfo}s. + * + * @author Robert Futrell + * @version 1.0 + */ +interface ConstantTypes { + + public static final int CONSTANT_Class = 7; + + public static final int CONSTANT_Fieldref = 9; + + public static final int CONSTANT_Methodref = 10; + + public static final int CONSTANT_InterfaceMethodref = 11; + + public static final int CONSTANT_String = 8; + + public static final int CONSTANT_Integer = 3; + + public static final int CONSTANT_Float = 4; + + public static final int CONSTANT_Long = 5; + + public static final int CONSTANT_Double = 6; + + public static final int CONSTANT_NameAndType = 12; + + public static final int CONSTANT_Utf8 = 1; + + public static final int CONSTANT_MethodHandle = 15; + + public static final int CONSTANT_MethodType = 16; + + public static final int CONSTANT_InvokeDynamic = 18; + +} diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantUtf8Info.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantUtf8Info.java new file mode 100644 index 00000000..133372ef --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantUtf8Info.java @@ -0,0 +1,135 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.classreader.constantpool; + +import java.io.UnsupportedEncodingException; + + +/** + * Class representing a CONSTANT_Utf8_info structure. + * + * @author Robert Futrell + * @version 1.0 + */ +public class ConstantUtf8Info extends ConstantPoolInfo { + + //private byte[] bytes; + private String representedString; + + + /** + * Constructor. + */ + public ConstantUtf8Info(byte[] bytes) { + super(CONSTANT_Utf8); + //this.bytes = bytes; + representedString = createRepresentedString(bytes); + } + + +// public byte[] getBytes() { +// return bytes; +// } + +/* + private static final boolean isBitSet(int b, int bit) { + return ((b>>bit)&1)>0; + } +*/ + + private String createRepresentedString(byte[] bytes) { +/* + StringBuilder sb = new StringBuilder(); + + int pos = 0; + while (pos>5)) { + // x = 110 (bits 10-6) + // y = 10 (bits 5-0) + // ch = ((x & 0x1f) << 6) + (y & 0x3f) + int x = b; + int y = bytes[pos++]; + char ch = (char)(((x&0x1f)<<6) + (y&0x3f)); + sb.append(ch); + } + + // chars in range '\u0800' - '\uFFFF'. + else if (15==(b>>4)) { + // x = 1110 (bits 15-12) + // y = 10 (bits 11-6) + // z = 10 (bits 5-0) + // ch = ((x & 0xf) << 12) + ((y & 0x3f) << 6) + (z & 0x3f) + int x = b; + int y = bytes[pos++]; + int z = bytes[pos++]; + char ch = (char)(((x&0xf)<<12) + ((y&0x3f)<<6) + (z&0x3f)); + sb.append(ch); + } + + // An unknown bit header. + else { + throw new InternalError("Unknown bit header in Utf8 string: " + + b); + } + + } + + representedString = sb.toString(); +*/ +try { + representedString = new String(bytes, "UTF-8"); +} catch (UnsupportedEncodingException uee) { // Never happens. + uee.printStackTrace(); + System.exit(0); +} + return representedString; + + } + + + /** + * Returns the string represented by this info. + * + * @param quoted Whether to add enclosing quotation marks, and "escape" + * any quotation marks in the represented string. + * @return The string represented. + */ + public String getRepresentedString(boolean quoted) { + if (!quoted) { + return representedString; + } + String temp = "\"" + representedString.replaceAll("\"", "\\\"") + "\""; + return temp; + } + + + /** + * Returns a string representation of this object. Useful for debugging. + * + * @return A string representation of this object. + */ + @Override + public String toString() { + return "[ConstantUtf8Info: " + representedString + + "]"; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/ASTNode.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/ASTNode.java new file mode 100644 index 00000000..dc362c0c --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/ASTNode.java @@ -0,0 +1,53 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.rjc.ast; + + +/** + * A node in a Java AST. + * + * @author Robert Futrell + * @version 1.0 + */ +public interface ASTNode { + + + /** + * Returns the "name" of this node. This will be the name of the method, + * the name of the member or local variable, etc. For {@link CodeBlock}s + * it will be {@link CodeBlock#NAME}.

    + * + * Note that this may not be unique. For example, a class with an + * overloaded method will have multiple methods with the same "name," + * just with different signatures. + * + * @return The "name" of this node. + */ + public String getName(); + + + /** + * Returns the end offset of the "name" of this node. + * + * @return The end offset. + */ + public int getNameEndOffset(); + + + /** + * Returns the start offset of the "name" of this node. + * + * @return The start offset. + */ + public int getNameStartOffset(); + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/AbstractASTNode.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/AbstractASTNode.java new file mode 100644 index 00000000..b5fbdfd3 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/AbstractASTNode.java @@ -0,0 +1,94 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.rjc.ast; + +import org.fife.rsta.ac.bsh.rjc.lexer.Offset; + + +/** + * Base implementation of an AST node. + * + * @author Robert Futrell + * @version 1.0 + */ +abstract class AbstractASTNode implements ASTNode { + + private String name; + private Offset startOffs; + private Offset endOffs; + + + protected AbstractASTNode(String name, Offset start) { + this(name, start, null); + } + + + protected AbstractASTNode(String name, Offset start, Offset end) { + this.name = name; + startOffs = start; + endOffs = end; + } + + + /** + * {@inheritDoc} + */ + public String getName() { + return name; + } + + + /** + * {@inheritDoc} + */ + public int getNameEndOffset() { + return endOffs!=null ? endOffs.getOffset() : Integer.MAX_VALUE; + } + + + /** + * {@inheritDoc} + */ + public int getNameStartOffset() { + return startOffs!=null ? startOffs.getOffset() : 0; + } + + + public void setDeclarationEndOffset(Offset end) { + endOffs = end; + } + + + /** + * Sets the start and end offsets of this node. + * + * @param start The start offset. + * @param end The end offset. + */ + protected void setDeclarationOffsets(Offset start, Offset end) { + startOffs = start; + endOffs = end; + } + + + /** + * Returns the name of this node (e.g. the value of {@link #getName()}. + * Subclasses can override this method if appropriate. + * + * @return A string representation of this node. + */ + @Override + public String toString() { + return getName(); + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/AbstractMember.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/AbstractMember.java new file mode 100644 index 00000000..d4ce3513 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/AbstractMember.java @@ -0,0 +1,63 @@ +/* + * 04/29/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.rjc.ast; + +import org.fife.rsta.ac.bsh.rjc.lang.Modifiers; +import org.fife.rsta.ac.bsh.rjc.lexer.Offset; + + +/** + * Code shared amongst all {@link Member} nodes. + * + * @author Robert Futrell + * @version 1.0 + */ +abstract class AbstractMember extends AbstractASTNode implements Member { + + private TypeDeclaration parentTypeDec; + + + protected AbstractMember(String name, Offset start) { + super(name, start); + } + + + protected AbstractMember(String name, Offset start, Offset end) { + super(name, start, end); + } + + + public TypeDeclaration getParentTypeDeclaration() { + return parentTypeDec; + } + + + /** + * {@inheritDoc} + */ + public boolean isStatic() { + Modifiers modifiers = getModifiers(); + return modifiers!=null && modifiers.isStatic(); + } + + + /** + * {@inheritDoc} + */ + public void setParentTypeDeclaration(TypeDeclaration dec) { + if (dec==null) { + throw new InternalError("Parent TypeDeclaration cannot be null"); + } + parentTypeDec = dec; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/AbstractTypeDeclarationNode.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/AbstractTypeDeclarationNode.java new file mode 100644 index 00000000..a0cc9bfe --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/AbstractTypeDeclarationNode.java @@ -0,0 +1,288 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.rjc.ast; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.fife.rsta.ac.bsh.rjc.lang.Modifiers; +import org.fife.rsta.ac.bsh.rjc.lexer.Offset; + + +public abstract class AbstractTypeDeclarationNode extends AbstractASTNode + implements TypeDeclaration { + + private Package pkg; + private Modifiers modifiers; + private TypeDeclaration parentType; + private List childTypes; + private Offset bodyStartOffs; + private Offset bodyEndOffs; + private boolean deprecated; + private String docComment; + + // --- "ClassBody"/"InterfaceBody"/EnumConstant fields --- + private List memberList; + + + public AbstractTypeDeclarationNode(String name, Offset start) { + super(name, start); + init(); + } + + + public AbstractTypeDeclarationNode(String name, Offset start, Offset end) { + super(name, start, end); + init(); + } + + + public void addMember(Member member) { + member.setParentTypeDeclaration(this); + memberList.add(member); + } + + + public void addTypeDeclaration(TypeDeclaration type) { + if (childTypes==null) { + childTypes = new ArrayList(1); // Usually small + } + type.setParentType(this); + childTypes.add(type); + } + + + public boolean getBodyContainsOffset(int offs) { + return offs>=getBodyStartOffset() && offs getFieldIterator() { + List fields = new ArrayList(); + for (Iterator i=getMemberIterator(); i.hasNext(); ) { + Member member = i.next(); + if (member instanceof Field) { + fields.add((Field)member); + } + } + return fields.iterator(); + } + + + public Member getMember(int index) { + return memberList.get(index); + } + + + public int getMemberCount() { + return memberList.size(); + } + + + /** + * {@inheritDoc} + */ + public Iterator getMemberIterator() { + return memberList.iterator(); + } + + + /** + * {@inheritDoc} + */ + public Iterator getMethodIterator() { + List methods = new ArrayList(); + for (Iterator i=getMemberIterator(); i.hasNext(); ) { + Member member = i.next(); + if (member instanceof Method) { + methods.add((Method)member); + } + } + return methods.iterator(); + } + + + /** + * {@inheritDoc} + */ + public List getMethodsByName(String name) { + List methods = new ArrayList(); + for (Iterator i=getMemberIterator(); i.hasNext(); ) { + Member member = i.next(); + if (member instanceof Method && name.equals(member.getName())) { + methods.add((Method)member); + } + } + return methods; + } + + + public Modifiers getModifiers() { + return modifiers; + } + + + /** + * {@inheritDoc} + */ + public String getName(boolean fullyQualified) { + String name = getName(); + if (fullyQualified) { + Package pkg = getPackage(); + if (pkg!=null) { + name = pkg.getName() + "." + name; + } + } + return name; + } + + + /** + * {@inheritDoc} + */ + public Package getPackage() { + return pkg; + } + + + /** + * {@inheritDoc} + */ + public TypeDeclaration getParentType() { + return parentType; + } + + + private void init() { + memberList = new ArrayList(); + } + + + public boolean isDeprecated() { + return deprecated; + } + + + /** + * {@inheritDoc} + */ + public boolean isStatic() { + return modifiers==null ? false : modifiers.isStatic(); + } + + + public void setBodyEndOffset(Offset end) { + bodyEndOffs = end; + } + + + public void setBodyStartOffset(Offset start) { + bodyStartOffs = start; + } + + + public void setDeprecated(boolean deprecated) { + this.deprecated = deprecated; + } + + + public void setDocComment(String comment) { + docComment = comment; + } + + + public void setModifiers(Modifiers modifiers) { + this.modifiers = modifiers; + } + + + /** + * Sets the package this type is in. + * + * @param pkg The package, or null if this is in the + * default package. + * @see #getPackage() + */ + public void setPackage(Package pkg) { + this.pkg = pkg; + } + + + /** + * {@inheritDoc} + */ + public void setParentType(TypeDeclaration parentType) { + this.parentType = parentType; + } + + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + if (modifiers!=null) { + sb.append(modifiers.toString()).append(' '); + } + sb.append(getTypeString()).append(' '); + sb.append(getName()); + return sb.toString(); + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/CodeBlock.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/CodeBlock.java new file mode 100644 index 00000000..f4c5076d --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/CodeBlock.java @@ -0,0 +1,203 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.rjc.ast; + +import java.util.ArrayList; +import java.util.List; + +import org.fife.rsta.ac.bsh.rjc.lang.Modifiers; +import org.fife.rsta.ac.bsh.rjc.lang.Type; +import org.fife.rsta.ac.bsh.rjc.lexer.Offset; +import org.fife.rsta.ac.bsh.rjc.lexer.TokenTypes; + + +/** + * A block of code in curly braces in a class.

    + * + * This class implements the Member interface because a block + * can be a member (say, a static block in a class declaration), but usually + * it's not actually a Member, but something else, e.g. the body + * of a method, or the content of an if-statement, etc. + * + * @author Robert Futrell + * @version 1.0 + */ +public class CodeBlock extends AbstractMember { + + /** + * The name of all CodeBlocks. + */ + public static final String NAME = "{...}"; + + private CodeBlock parent; + private List children; + private List localVars; + private boolean isStatic; + + + public CodeBlock(boolean isStatic, Offset startOffs) { + super(NAME, startOffs); + this.isStatic = isStatic; + } + + + public void add(CodeBlock child) { + if (children==null) { + children = new ArrayList(); + } + children.add(child); + child.setParent(this); + } + + + public void addLocalVariable(LocalVariable localVar) { + if (localVars==null) { + localVars = new ArrayList(); + } + localVars.add(localVar); + } + + + public boolean containsOffset(int offs) { + // Do endOffset first since we'll often iterate from first CodeBlock + // to last, so checking it first should be faster. + return getNameEndOffset()>=offs && getNameStartOffset()<=offs; + } + + + public CodeBlock getChildBlock(int index) { + return children.get(index); + } + + + public int getChildBlockCount() { + return children==null ? 0 : children.size(); + } + + + /** + * Returns the deepest code block nested under this one (or this one + * itself) containing a given offset. + * + * @param offs The offset to look for. + * @return The deepest-nested code block containing the offset, or + * null if this code block and none of its children + * contain the offset. + */ + public CodeBlock getDeepestCodeBlockContaining(int offs) { + if (!containsOffset(offs)) { + return null; + } + for (int i=0; i getLocalVarsBefore(int offs) { + + List vars = new ArrayList(); + + if (localVars!=null) { + for (int i=0; inull, since blocks don't have types. + * + * @return null always. + */ + public Type getType() { + return null; + } + + + public boolean isDeprecated() { + return false; + } + + + /** + * Returns whether this block is a static block (in a class declaration). + * + * @return Whether this is a static code block. + */ + @Override + public boolean isStatic() { + return isStatic; + } + + + public void setParent(CodeBlock parent) { + this.parent = parent; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/CompilationUnit.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/CompilationUnit.java new file mode 100644 index 00000000..0aef9e7f --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/CompilationUnit.java @@ -0,0 +1,290 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.rjc.ast; + +import java.awt.Point; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.fife.rsta.ac.bsh.rjc.lang.Annotation; +import org.fife.rsta.ac.bsh.rjc.lexer.Offset; +import org.fife.rsta.ac.bsh.rjc.lexer.Token; +import org.fife.rsta.ac.bsh.rjc.notices.ParserNotice; + + +/** + * A CompilationUnit is the root node of an AST for a Java + * source file. + * + *

    + * CompilationUnit:
    + *    [[Annotations] 'package' QualifiedIdentifier ';' ] {ImportDeclaration} {TypeDeclaration}
    + * 
    + * + * @author Robert Futrell + * @version 1.0 + */ +public class CompilationUnit extends AbstractASTNode + implements TypeDeclarationContainer { + + private List annotations; + private Package pkg; + private List imports; + private List typeDeclarations; + private List notices; + + private static final Offset ZERO_OFFSET = new ZeroOffset(); + + + public CompilationUnit(String name) { + super(name, ZERO_OFFSET); + imports = new ArrayList(3); // Usually not many, + typeDeclarations = new ArrayList(1); // Usually only 1 + } + + + public void addImportDeclaration(ImportDeclaration dec) { + imports.add(dec); + } + + + /** + * Shorthand for "addParserNotice(new ParserNotice(t, msg))". + * + * @param t + * @param msg + */ + public void addParserNotice(Token t, String msg) { + addParserNotice(new ParserNotice(t, msg)); + } + + + public void addParserNotice(ParserNotice notice) { + if (notices==null) { + notices = new ArrayList(); + notices.add(notice); + } + } + + + public void addTypeDeclaration(TypeDeclaration typeDec) { + typeDeclarations.add(typeDec); + } + + + public int getAnnotationCount() { + return annotations.size(); + } + + + public Iterator getAnnotationIterator() { + return annotations.iterator(); + } + + + /** + * Returns the deepest-nested type declaration that contains a given + * offset. + * + * @param offs The offset. + * @return The deepest-nested type declaration containing the offset, or + * null if the offset is outside of any type + * declaration (such as in the import statements, etc.). + * @see #getTypeDeclarationAtOffset(int) + */ + public TypeDeclaration getDeepestTypeDeclarationAtOffset(int offs) { + + TypeDeclaration td = getTypeDeclarationAtOffset(offs); + + if (td!=null) { + TypeDeclaration next = td.getChildTypeAtOffset(offs); + while (next!=null) { + td = next; + next = td.getChildTypeAtOffset(offs); + } + } + + return td; + + } + + + /** + * TODO: Return range for more instances than just class methods. + * Also handle child TypeDeclarations. + * + * @param offs + * @return The starting and ending offset of the enclosing method range. + */ + public Point getEnclosingMethodRange(int offs) { + + Point range = null; + + for (Iterator i=getTypeDeclarationIterator(); i.hasNext(); ) { + + TypeDeclaration td = i.next(); + int start = td.getBodyStartOffset(); + int end = td.getBodyEndOffset(); + + if (offs>=start && offs<=end) { + + if (td instanceof NormalClassDeclaration) { + NormalClassDeclaration ncd = (NormalClassDeclaration)td; + for (Iterator j=ncd.getMemberIterator(); j.hasNext(); ) { + Member m = j.next(); + if (m instanceof Method) { + Method method = (Method)m; + CodeBlock body = method.getBody(); + if (body!=null) { + int start2 = method.getNameStartOffset(); + //int start2 = body.getStartOffset(); + int end2 = body.getNameEndOffset(); + if (offs>=start2 && offs<=end2) { + range = new Point(start2, end2); + break; + } + } + } + } + } + + if (range==null) { // Default to the entire class' body. + range = new Point(start, end); + } + + } + + } + + return range; + + } + + + public int getImportCount() { + return imports.size(); + } + + + /** + * Returns the import declarations of this compilation unit. This is a + * copy of the list of imports, but the actual individual + * {@link ImportDeclaration}s are not copies, so modifying them will modify + * this compilation unit! + * + * @return A list or imports, or an empty list if there are none. + */ + public List getImports() { + return new ArrayList(imports); + } + + + public Iterator getImportIterator() { + return imports.iterator(); + } + + + /** + * Returns the package of this compilation unit. + * + * @return The package of this compilation unit, or null if + * this compilation unit is not in a package. + * @see #getPackageName() + */ + public Package getPackage() { + return pkg; + } + + + /** + * Returns the fully-qualified package name of this compilation unit. + * + * @return The package name, or null if this compilation unit + * is not in a package (in the default package). + * @see #getPackage() + */ + public String getPackageName() { + return pkg==null ? null : pkg.getName(); + } + + + public ParserNotice getParserNotice(int index) { + if (notices==null) { + throw new IndexOutOfBoundsException("No parser notices available"); + } + return notices.get(index); + } + + + public int getParserNoticeCount() { + return notices==null ? 0 : notices.size(); + } + + + public TypeDeclaration getTypeDeclaration(int index) { + return typeDeclarations.get(index); + } + + + /** + * Returns the type declaration in this file that contains the specified + * offset. + * + * @param offs The offset. + * @return The type declaration, or null if the offset is + * outside of any type declaration. + * @see #getDeepestTypeDeclarationAtOffset(int) + */ + public TypeDeclaration getTypeDeclarationAtOffset(int offs) { + + TypeDeclaration typeDec = null; + + for (TypeDeclaration td : typeDeclarations) { + if (td.getBodyContainsOffset(offs)) { + typeDec = td; + break; + } + } + + return typeDec; + + } + + + public int getTypeDeclarationCount() { + return typeDeclarations.size(); + } + + + public Iterator getTypeDeclarationIterator() { + return typeDeclarations.iterator(); + } + + + public void setPackage(Package pkg) { + this.pkg = pkg; + } + + + /** + * An offset that always returns 0. + */ + private static class ZeroOffset implements Offset { + + public int getOffset() { + return 0; + } + + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/EnumBody.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/EnumBody.java new file mode 100644 index 00000000..db559d83 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/EnumBody.java @@ -0,0 +1,46 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.rjc.ast; + +import org.fife.rsta.ac.bsh.rjc.lexer.Offset; + + +/** + * An EnumBody. + * + *
    + * EnumBody:
    + *    '{' [EnumConstants] [,] [EnumBodyDeclarations] '}'
    + *
    + *
    + * EnumConstants:
    + *    EnumConstant
    + *    EnumConstants , EnumConstant
    + *
    + * EnumConstant:
    + *    Annotations Identifier [Arguments] [ClassBody]
    + *
    + * EnumBodyDeclarations:
    + *    ; {ClassBodyDeclaration}
    + * 
    + * + * @author Robert Futrell + * @version 1.0 + */ +public class EnumBody extends AbstractASTNode { + + + public EnumBody(String name, Offset start) { + super(name, start); + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/EnumDeclaration.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/EnumDeclaration.java new file mode 100644 index 00000000..07416122 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/EnumDeclaration.java @@ -0,0 +1,36 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.rjc.ast; + +import org.fife.rsta.ac.bsh.rjc.lexer.Scanner; + + +public class EnumDeclaration extends AbstractTypeDeclarationNode { + +// private EnumBody enumBody; + + + public EnumDeclaration(Scanner s, int offs, String name) { + super(name, s.createOffset(offs), s.createOffset(offs+name.length())); + } + + + public String getTypeString() { + return "enum"; + } + + +// public void setEnumBody(EnumBody enumBody) { +// this.enumBody = enumBody; +// } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/Field.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/Field.java new file mode 100644 index 00000000..21b42b95 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/Field.java @@ -0,0 +1,68 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.rjc.ast; + +import org.fife.rsta.ac.bsh.rjc.lang.Modifiers; +import org.fife.rsta.ac.bsh.rjc.lang.Type; +import org.fife.rsta.ac.bsh.rjc.lexer.Scanner; +import org.fife.rsta.ac.bsh.rjc.lexer.Token; + + +public class Field extends AbstractMember { + + private Modifiers modifiers; + private Type type; + private boolean deprecated; + private String docComment; + + + public Field(Scanner s, Modifiers modifiers, Type type, Token t) { + super(t.getLexeme(), s.createOffset(t.getOffset())); + setDeclarationEndOffset(s.createOffset(t.getOffset() + t.getLength())); + if (modifiers==null) { + modifiers = new Modifiers(); + } + this.modifiers = modifiers; + this.type = type; + } + + + public String getDocComment() { + return docComment; + } + + + public Modifiers getModifiers() { + return modifiers; + } + + + public Type getType() { + return type; + } + + + public boolean isDeprecated() { + return deprecated; + } + + + public void setDeprecated(boolean deprecated) { + this.deprecated = deprecated; + } + + + public void setDocComment(String comment) { + docComment = comment; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/FormalParameter.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/FormalParameter.java new file mode 100644 index 00000000..c927cf66 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/FormalParameter.java @@ -0,0 +1,61 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.rjc.ast; + +import java.util.List; + +import org.fife.rsta.ac.bsh.rjc.lang.Annotation; +import org.fife.rsta.ac.bsh.rjc.lang.Type; +import org.fife.rsta.ac.bsh.rjc.lexer.Scanner; + + +/** + * A parameter to a method. + * + * @author Robert Futrell + * @version 1.0 + */ +/* + * FormalParameter: + * ['final'] [Annotations] Type VariableDeclaratorId + * + * VariableDeclaratorId: + * Identifier { "[" "]" } + */ +public class FormalParameter extends LocalVariable { + + private List annotations; + + + public FormalParameter(Scanner s, boolean isFinal, + Type type, int offs, String name, List annotations) { + super(s, isFinal, type, offs, name); + this.annotations = annotations; + } + + + public int getAnnotationCount() { + return annotations==null ? 0 : annotations.size(); + } + + + /** + * Overridden to return "getType() getName()". + * + * @return This parameter, as a string. + */ + @Override + public String toString() { + return getType() + " " + getName(); + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/ImportDeclaration.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/ImportDeclaration.java new file mode 100644 index 00000000..865a5fbf --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/ImportDeclaration.java @@ -0,0 +1,48 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.rjc.ast; + +import org.fife.rsta.ac.bsh.rjc.lexer.Scanner; + + +/** + * An import declaration in a class file. + * + * @author Robert Futrell + * @version 1.0 + */ +public class ImportDeclaration extends AbstractASTNode { + + private boolean isStatic; + + + public ImportDeclaration(Scanner s, int offs, String info, boolean isStatic) { + super(info, s.createOffset(offs), s.createOffset(offs+info.length())); + setStatic(isStatic); + } + + + public boolean isStatic() { + return isStatic; + } + + + public boolean isWildcard() { + return getName().endsWith(".*"); + } + + + public void setStatic(boolean isStatic) { + this.isStatic = isStatic; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/LocalVariable.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/LocalVariable.java new file mode 100644 index 00000000..ddf7946d --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/LocalVariable.java @@ -0,0 +1,47 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.rjc.ast; + +import org.fife.rsta.ac.bsh.rjc.lang.Type; +import org.fife.rsta.ac.bsh.rjc.lexer.Scanner; + + +/** + * Base class for local variables and formal parameters. + * + * @author Robert Futrell + * @version 1.0 + */ +public class LocalVariable extends AbstractASTNode { + + private boolean isFinal; + private Type type; + + + public LocalVariable(Scanner s, boolean isFinal, + Type type, int offs, String name) { + super(name, s.createOffset(offs), s.createOffset(offs+name.length())); + this.isFinal = isFinal; + this.type = type; + } + + + public Type getType() { + return type; + } + + + public boolean isFinal() { + return isFinal; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/Member.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/Member.java new file mode 100644 index 00000000..6eb38d25 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/Member.java @@ -0,0 +1,63 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.rjc.ast; + +import org.fife.rsta.ac.bsh.rjc.lang.Modifiers; +import org.fife.rsta.ac.bsh.rjc.lang.Type; + + +/** + * A marker for a member of a class or interface. + * + * @author Robert Futrell + * @version 1.0 + */ +public interface Member extends ASTNode { + + + public String getDocComment(); + + + public int getNameEndOffset(); + + + public int getNameStartOffset(); + + + public Modifiers getModifiers(); + + + public String getName(); + + + public TypeDeclaration getParentTypeDeclaration(); + + + public Type getType(); + + + public boolean isDeprecated(); + + + /** + * Shortcut for getModifiers().isStatic(); useful since + * getModifiers() may return null. + * + * @return Whether this member is static. + * @see #getModifiers() + */ + public boolean isStatic(); + + + public void setParentTypeDeclaration(TypeDeclaration dec); + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/Method.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/Method.java new file mode 100644 index 00000000..fbdbe134 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/Method.java @@ -0,0 +1,148 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.rjc.ast; + +import java.util.Iterator; +import java.util.List; + +import org.fife.rsta.ac.bsh.rjc.lang.Modifiers; +import org.fife.rsta.ac.bsh.rjc.lang.Type; +import org.fife.rsta.ac.bsh.rjc.lexer.Scanner; +import org.fife.rsta.ac.bsh.rjc.lexer.Token; + + +// TODO: Implement me correctly +public class Method extends AbstractMember { + + private Modifiers modifiers; + private Type type; + private List parameters; + private List thrownTypeNames; + private CodeBlock body; + private boolean deprecated; + private String docComment; + + + public Method(Scanner s, Modifiers modifiers, Type type, Token nameToken, + List params, List thrownTypeNames) { + super(nameToken.getLexeme(), + s.createOffset(nameToken.getOffset()), + s.createOffset(nameToken.getOffset() + nameToken.getLength())); + if (modifiers==null) { + modifiers = new Modifiers(); + } + this.modifiers = modifiers; + this.type = type; + this.parameters = params; + this.thrownTypeNames = thrownTypeNames; + } + + + public CodeBlock getBody() { + return body; + } + + + public boolean getBodyContainsOffset(int offs) { + return offs>=getBodyStartOffset() && offs getParameterIterator() { + return parameters.iterator(); + } + + + public int getThrownTypeNameCount() { + return thrownTypeNames==null ? 0 : thrownTypeNames.size(); + } + + + public Type getType() { + return type; + } + + + public boolean isConstructor() { + return type==null; + } + + + public boolean isDeprecated() { + return deprecated; + } + + + public void setBody(CodeBlock body) { + this.body = body; + } + + + public void setDeprecated(boolean deprecated) { + this.deprecated = deprecated; + } + + + public void setDocComment(String comment) { + docComment = comment; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/NormalClassDeclaration.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/NormalClassDeclaration.java new file mode 100644 index 00000000..3bb217f5 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/NormalClassDeclaration.java @@ -0,0 +1,142 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.rjc.ast; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.fife.rsta.ac.bsh.rjc.lang.Type; +import org.fife.rsta.ac.bsh.rjc.lang.TypeParameter; +import org.fife.rsta.ac.bsh.rjc.lexer.Scanner; + + +/** + * A class declaration: + * + *
    + * NormalClassDeclaration:
    + *    'class' Identifier [TypeParameters] ['extends' Type] ['implements' TypeList] ClassBody
    + * 
    + * + * @author Robert Futrell + * @version 1.0 + */ +public class NormalClassDeclaration extends AbstractTypeDeclarationNode { + + // --- "NormalClassDeclaration" fields --- + private List typeParams; + private Type extendedType; + private List implementedList; + + + public NormalClassDeclaration(Scanner s, int offs, String className) { + super(className, s.createOffset(offs), s.createOffset(offs+className.length())); + implementedList = new ArrayList(0); // Usually not many + // If parsing java.lang.Object.java, setExtendedType(null) should be + // called. This is here for all other classes without an explicit + // super class declared. + extendedType = new Type("java.lang.Object"); + } + + + public void addImplemented(Type implemented) { + implementedList.add(implemented); + } + + + public Type getExtendedType() { + return extendedType; + } + + + public int getImplementedCount() { + return implementedList.size(); + } + + + public Iterator getImplementedIterator() { + return implementedList.iterator(); + } + + + /** + * Gets the method in this class that contains a given offset. + * + * @param offs The offset. + * @return The method containing the offset, or null if no + * method in this class contains the offset. + */ + public Method getMethodContainingOffset(int offs) { + for (Iterator i=getMethodIterator(); i.hasNext(); ) { + Method method = i.next(); + if (method.getBodyContainsOffset(offs)) { + return method; + } + } + return null; + } + + + public List getTypeParameters() { + return typeParams; + } + + + public String getTypeString() { + return "class"; + } + + + /** + * Returns whether a Type and a type name are type + * compatible. This method currently is a sham! + * + * @param type + * @param typeName + * @return + */ + // TODO: Get me working! Probably need better parameters passed in!!! + private boolean isTypeCompatible(Type type, String typeName) { + + String typeName2 = type.getName(false); + + // Remove generics info for now + // TODO: Handle messy generics cases + int lt = typeName2.indexOf('<'); + if (lt>-1) { + String arrayDepth = null; + int brackets = typeName2.indexOf('[', lt); + if (brackets>-1) { + arrayDepth = typeName2.substring(brackets); + } + typeName2 = typeName2.substring(lt); + if (arrayDepth!=null) { + typeName2 += arrayDepth; + } + } + + return typeName2.equalsIgnoreCase(typeName); + + } + + + public void setExtendedType(Type type) { + extendedType = type; + } + + + public void setTypeParameters(List typeParams) { + this.typeParams = typeParams; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/NormalInterfaceDeclaration.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/NormalInterfaceDeclaration.java new file mode 100644 index 00000000..49b47e23 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/NormalInterfaceDeclaration.java @@ -0,0 +1,63 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.rjc.ast; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.fife.rsta.ac.bsh.rjc.lang.Type; +import org.fife.rsta.ac.bsh.rjc.lexer.Scanner; + + +/** + * An interface declaration: + * + *
    + * NormalInterfaceDeclaration:
    + *    'interface' Identifier [TypeParameters] ['extends' TypeList] InterfaceBody
    + * 
    + * + * @author Robert Futrell + * @version 1.0 + */ +public class NormalInterfaceDeclaration extends AbstractTypeDeclarationNode { + + private List extendedList; + + + public NormalInterfaceDeclaration(Scanner s, int offs, String name) { + super(name, s.createOffset(offs), s.createOffset(offs+name.length())); + extendedList = new ArrayList(1); // Usually small + } + + + public void addExtended(Type extended) { + extendedList.add(extended); + } + + + public int getExtendedCount() { + return extendedList.size(); + } + + + public Iterator getExtendedIterator() { + return extendedList.iterator(); + } + + + public String getTypeString() { + return "interface"; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/Package.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/Package.java new file mode 100644 index 00000000..2dba37be --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/Package.java @@ -0,0 +1,24 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.rjc.ast; + +import org.fife.rsta.ac.bsh.rjc.lexer.Scanner; + + +public class Package extends AbstractASTNode { + + + public Package(Scanner s, int offs, String pkg) { + super(pkg, s.createOffset(offs), s.createOffset(offs+pkg.length())); + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/TypeDeclaration.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/TypeDeclaration.java new file mode 100644 index 00000000..05b7a912 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/TypeDeclaration.java @@ -0,0 +1,173 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.rjc.ast; + +import java.util.Iterator; +import java.util.List; + +import org.fife.rsta.ac.bsh.rjc.lang.Modifiers; + + +public interface TypeDeclaration extends ASTNode, TypeDeclarationContainer { + + + public boolean getBodyContainsOffset(int offs); + + + public int getBodyEndOffset(); + + + public int getBodyStartOffset(); + + + public TypeDeclaration getChildType(int index); + + + /** + * Returns the child type declaration of this one that contains the + * specified offset, if any. + * + * @param offs The offset. + * @return The type declaration, or null if the offset is + * outside of any child type declaration. + */ + public TypeDeclaration getChildTypeAtOffset(int offs); + + + public int getChildTypeCount(); + + + public String getDocComment(); + + + /** + * Returns an iterator over all fields defined in this type. + * + * @return The iterator. + * @see #getMethodIterator() + * @see #getMemberIterator() + */ + public Iterator getFieldIterator(); + + + public Member getMember(int index); + + + public int getMemberCount(); + + + /** + * Returns an iterator over all members of this type. Note + * that an exception may be thrown if a method is added to this type + * while this iterator is being used. + * + * @return The iterator. + * @see #getMethodIterator() + */ + public Iterator getMemberIterator(); + + + /** + * Returns an iterator over all methods defined in this type. + * + * @return The iterator. + * @see #getFieldIterator() + * @see #getMemberIterator() + */ + public Iterator getMethodIterator(); + + + /** + * Returns all methods declared in this type with the given name. Does + * not check for methods with this name in subclasses. + * + * @param name The name to check for. + * @return Any method overloads with that name, or an empty list if none. + */ + public List getMethodsByName(String name); + + + /** + * Returns the modifiers of this type declaration. + * + * @return The modifier list. This may be null if no + * modifiers were specified. + */ + public Modifiers getModifiers(); + + + /** + * Returns the name of this type, unqualified. + * + * @return The name of this type. + * @see #getName(boolean) + */ + public String getName(); + + + /** + * Returns the name of this type. + * + * @param fullyQualified Whether the name returned should be fully + * qualified. + * @return The type's name. + * @see #getName() + */ + public String getName(boolean fullyQualified); + + + /** + * Returns the package this type is in. + * + * @return The package, or null if it's in the default package. + */ + public Package getPackage(); + + + /** + * Returns the parent type declaration. + * + * @return The parent type declaration, or null if there isn't + * one. + * @see #setParentType(TypeDeclaration) + */ + public TypeDeclaration getParentType(); + + + public String getTypeString(); + + + public boolean isDeprecated(); + + + /** + * Shortcut for getModifiers().isStatic(); useful since + * getModifiers() may return null. + * + * @return Whether this type declaration is static. + * @see #getModifiers() + */ + public boolean isStatic(); + + + public void setDocComment(String comment); + + + /** + * Sets the parent type declaration for this type declaration. + * + * @param parentType The parent type declaration. + * @see #getParentType() + */ + public void setParentType(TypeDeclaration parentType); + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/TypeDeclarationContainer.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/TypeDeclarationContainer.java new file mode 100644 index 00000000..c76c4087 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/TypeDeclarationContainer.java @@ -0,0 +1,27 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.rjc.ast; + + +/** + * Interface for tree nodes that can hold type declarations (e.g. + * {@link CompilationUnit}s and {@link TypeDeclaration}s. + * + * @author Robert Futrell + * @version 1.0 + */ +public interface TypeDeclarationContainer { + + + public void addTypeDeclaration(TypeDeclaration typeDec); + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/lang/Annotation.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/lang/Annotation.java new file mode 100644 index 00000000..88db6ddb --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/rjc/lang/Annotation.java @@ -0,0 +1,30 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.rjc.lang; + + +public class Annotation { + + private Type type; + + + public Annotation(Type type) { + this.type = type; + } + + + @Override + public String toString() { + return "@" + type.toString(); + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/lang/Modifiers.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/lang/Modifiers.java new file mode 100644 index 00000000..5ca4eed5 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/rjc/lang/Modifiers.java @@ -0,0 +1,193 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.rjc.lang; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.fife.rsta.ac.bsh.rjc.lexer.TokenTypes; + + +/** + * Wrapper around modifiers to a member. + * + * @author Robert Futrell + * @version 1.0 + */ +public class Modifiers { + + public static final Integer ABSTRACT = new Integer(1024); + public static final Integer FINAL = new Integer(16); + public static final Integer INTERFACE = new Integer(512); + public static final Integer NATIVE = new Integer(256); + public static final Integer PRIVATE = new Integer(2); + public static final Integer PROTECTED = new Integer(4); + public static final Integer PUBLIC = new Integer(1); + public static final Integer STATIC = new Integer(8); + public static final Integer STRICTFP = new Integer(2048); + public static final Integer SYNCHRONIZED = new Integer(32); + public static final Integer TRANSIENT = new Integer(128); + public static final Integer VOLATILE = new Integer(64); + + private List modifiers; + private List annotations; + + + private static final Map MODIFIER_TEXT + = new HashMap() { + + private static final long serialVersionUID = 1L; + + { + put(ABSTRACT, "abstract"); + put(FINAL, "final"); + put(INTERFACE, "interface"); + put(NATIVE, "native"); + put(PRIVATE, "private"); + put(PROTECTED, "protected"); + put(PUBLIC, "public"); + put(STATIC, "static"); + put(STRICTFP, "strictfp"); + put(SYNCHRONIZED, "synchronized"); + put(TRANSIENT, "transient"); + put(VOLATILE, "volatile"); + } + }; + + + public Modifiers() { + modifiers = new ArrayList(1); // Usually not many. + annotations = new ArrayList(0); // Often 0 or 1 (@Deprecated) + } + + + public void addAnnotation(Annotation annotation) { + annotations.add(annotation); + } + + + public boolean addModifier(int tokenType) { + + Integer key = null; + + switch (tokenType) { + case TokenTypes.KEYWORD_ABSTRACT: + key = ABSTRACT; + break; + case TokenTypes.KEYWORD_FINAL: + key = FINAL; + break; + case TokenTypes.KEYWORD_INTERFACE: + key = INTERFACE; + break; + case TokenTypes.KEYWORD_NATIVE: + key = NATIVE; + break; + case TokenTypes.KEYWORD_PRIVATE: + key = PRIVATE; + break; + case TokenTypes.KEYWORD_PROTECTED: + key = PROTECTED; + break; + case TokenTypes.KEYWORD_PUBLIC: + key = PUBLIC; + break; + case TokenTypes.KEYWORD_STATIC: + key = STATIC; + break; + case TokenTypes.KEYWORD_STRICTFP: + key = STRICTFP; + break; + case TokenTypes.KEYWORD_SYNCHRONIZED: + key = SYNCHRONIZED; + break; + case TokenTypes.KEYWORD_TRANSIENT: + key = TRANSIENT; + break; + case TokenTypes.KEYWORD_VOLATILE: + key = VOLATILE; + break; + default: + throw new IllegalArgumentException("Invalid tokenType: " + + tokenType); + } + + int pos = Collections.binarySearch(modifiers, key); + if (pos<0) { + // pos = -insertionPoint - 1 + int insertionPoint = -(pos+1); + modifiers.add(insertionPoint, key); + } + + return pos<0; + + } + + + private boolean containsModifier(Integer modifierKey) { + return Collections.binarySearch(modifiers, modifierKey)>=0; + } + + + public boolean isAbstract() { + return containsModifier(ABSTRACT); + } + + + public boolean isFinal() { + return containsModifier(FINAL); + } + + + public boolean isPrivate() { + return containsModifier(PRIVATE); + } + + + public boolean isProtected() { + return containsModifier(PROTECTED); + } + + + public boolean isPublic() { + return containsModifier(PUBLIC); + } + + + public boolean isStatic() { + return containsModifier(STATIC); + } + + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + for (int i=0; i0) { + sb.append(' '); + } + } + for (int i=0; i + * Type: + * Identifier [TypeArguments] { . Identifier [TypeArguments] } {[]} + * BasicType + * + * + * @author Robert Futrell + * @version 1.0 + */ +public class Type { + + private List identifiers; + private List> typeArguments; + private int bracketPairCount; + + + public Type() { + identifiers = new ArrayList(1); + typeArguments = new ArrayList>(1); + } + + + public Type(String identifier) { + this(); + addIdentifier(identifier, null); + } + + + public Type(String identifier, int bracketPairCount) { + this(); + addIdentifier(identifier, null); + setBracketPairCount(bracketPairCount); + } + + + /** + * Adds an identifier to this type. + * + * @param identifier The identifier. + * @param typeArgs The type arguments for the identifier. This may be + * null or an empty list if there are none. + */ + public void addIdentifier(String identifier, List typeArgs) { + identifiers.add(identifier); + typeArguments.add(typeArgs); + } + + + public int getIdentifierCount() { + return identifiers.size(); + } + + + /** + * Returns the name of this type. + * + * @param fullyQualified Whether the returned value should be + * fully qualified. + * @return The name of this type. This will include type arguments, + * if any. + * @see #getName(boolean, boolean) + */ + public String getName(boolean fullyQualified) { + return getName(fullyQualified, true); + } + + + /** + * Returns the name of this type. + * + * @param fullyQualified Whether the returned value should be + * fully qualified. + * @param addTypeArgs Whether type arguments should be at the end of + * the returned string, if any. + * @return The name of this type. + * @see #getName(boolean) + */ + public String getName(boolean fullyQualified, boolean addTypeArgs) { + + StringBuilder sb = new StringBuilder(); + + int count = identifiers.size(); + int start = fullyQualified ? 0 : count-1; + for (int i=start; i typeArgs = typeArguments.get(i); + int typeArgCount = typeArgs.size(); + if (typeArgCount>0) { + sb.append('<'); + for (int j=0; j'); + } + } + if (i getTypeArguments(int index) { + return typeArguments.get(index); + } + + + /* + * MethodDeclaratorRest allows bracket pairs after its FormalParameters, + * which increment the array depth of the return type. + */ + public void incrementBracketPairCount(int count) { + bracketPairCount += count; + } + + + /** + * Returns whether this type is an array. + * + * @return Whether this type is an array. + */ + public boolean isArray() { + return bracketPairCount>0; + } + + + public boolean isBasicType() { + boolean basicType = false; + if (!isArray() && identifiers.size()==1 && typeArguments.get(0)==null) { + String str = identifiers.get(0); + basicType = "byte".equals(str) || + "float".equals(str) || + "double".equals(str) || + "int".equals(str) || + "short".equals(str) || + "long".equals(str) || + "boolean".equals(str); + } + return basicType; + } + + + public void setBracketPairCount(int count) { + bracketPairCount = count; + } + + + /** + * Returns a string representation of this type. The type name will be + * fully qualified. + * + * @return A string representation of this type. + * @see #getName(boolean) + */ + @Override + public String toString() { + return getName(true); + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/lang/TypeArgument.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/lang/TypeArgument.java new file mode 100644 index 00000000..9ec73636 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/rjc/lang/TypeArgument.java @@ -0,0 +1,61 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.rjc.lang; + + +public class TypeArgument { + + public static final int NOTHING = 0; + public static final int EXTENDS = 1; + public static final int SUPER = 2; + + private Type type; + private int doesExtend; + private Type otherType; + + + public TypeArgument(Type type) { + this.type = type; + } + + + public TypeArgument(Type type, int doesExtend, Type otherType) { + if (doesExtend<0 || doesExtend>2) { + throw new IllegalArgumentException("Illegal doesExtend: " + doesExtend); + } + this.type = type; + this.doesExtend = doesExtend; + this.otherType = otherType; + } + + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + if (type==null) { + sb.append('?'); + } + else { + sb.append(type.toString()); + } + if (doesExtend==EXTENDS) { + sb.append(" extends "); + sb.append(otherType.toString()); + } + else if (doesExtend==SUPER) { + sb.append(" super "); + sb.append(otherType.toString()); + } + return sb.toString(); + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/lang/TypeParameter.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/lang/TypeParameter.java new file mode 100644 index 00000000..3741a054 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/rjc/lang/TypeParameter.java @@ -0,0 +1,57 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.rjc.lang; + +import java.util.ArrayList; +import java.util.List; + +import org.fife.rsta.ac.bsh.rjc.lexer.Token; + + +/** + * A TypeParameter. + * + *
    + * TypeParameter:
    + *    Identifier ['extends' Bound]
    + * 
    + * Bound:
    + *    Type { '&' Type }
    + * 
    + * + * @author Robert Futrell + * @version 1.0 + */ +public class TypeParameter { + + private Token name; + private List bounds; + + + public TypeParameter(Token name) { + this.name = name; + } + + + public void addBound(Type bound) { + if (bounds==null) { + bounds = new ArrayList(1); // Usually just 1 + } + bounds.add(bound); + } + + + public String getName() { + return name.getLexeme(); + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/lang/Variable.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/lang/Variable.java new file mode 100644 index 00000000..32920a14 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/rjc/lang/Variable.java @@ -0,0 +1,51 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.rjc.lang; + +import org.fife.rsta.ac.bsh.rjc.lexer.Token; + + +/** + * Base class for variable type (local variables, formal parameters...). + * + * @author Robert Futrell + * @version 1.0 + */ +public abstract class Variable { + + private boolean isFinal; + private Type type; + private Token name; + + + public Variable(boolean isFinal, Type type, Token name) { + this.isFinal = isFinal; + this.type = type; + this.name = name; + } + + + public String getName() { + return name.getLexeme(); + } + + + public Type getType() { + return type; + } + + + public boolean isFinal() { + return isFinal; + } + + +} diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/Offset.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/Offset.java new file mode 100644 index 00000000..6b4e981a --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/Offset.java @@ -0,0 +1,33 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.rjc.lexer; + + +/** + * An offset into Java source. This is an interface so we can wrap + * javax.swing.text.Position instances when parsing code in a + * JTextComponent, so these offsets can get tracked. + * + * @author Robert Futrell + * @version 1.0 + */ +public interface Offset { + + + /** + * Returns the offset into the source. + * + * @return The offset. + */ + public int getOffset(); + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/Scanner.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/Scanner.java new file mode 100644 index 00000000..4c0d4c87 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/Scanner.java @@ -0,0 +1,870 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.rjc.lexer; + +import java.io.EOFException; +import java.io.IOException; +import java.io.Reader; +import java.util.List; +import java.util.Stack; +import javax.swing.text.BadLocationException; +import javax.swing.text.Document; +import javax.swing.text.Position; + + +/** + * A scanner that allows the user to "push back" tokens. This scanner + * allows arbitrary lookahead. + * + * @author Robert Futrell + * @version 1.0 + */ +public class Scanner { + + private static final boolean DEBUG = false; + + /** + * The scanner we delegate to. + */ + private SourceCodeScanner s; + + /** + * Stack of tokens that have been "pushed back." + */ + private Stack stack; + + /** + * The depth in which we're in TypeArguments or TypeParameters. + */ + private int typeArgLevel; + + /** + * If we are parsing text in a Swing JTextComponent, this + * should be the document of that component. + */ + private Document doc; + + /** + * The most recently lexed token, or null if EOS was + * reached. + */ + private Token mostRecentToken; + + + /** + * Constructor. This scanner will return no tokens unless some are pushed + * onto it via {@link #yyPushback(Token)}. + */ + public Scanner() { + this((Reader)null); + } + + + /** + * Constructor. This scanner will only return those tokens pushed onto it. + * + * @param tokens Tokens to return. + */ + public Scanner(List tokens) { + stack = new Stack(); + for (int i=tokens.size()-1; i>=0; i--) { + stack.push(tokens.get(i)); + } + } + + + /** + * Constructor. + * + * @param r The stream to read from. + */ + public Scanner(Reader r) { + s = r!=null ? new SourceCodeScanner(r) : null; + s.setKeepLastDocComment(true); + stack = new Stack(); + } + + +/** + * This method is just here for debugging purposes to make sure + * our parser is sound. + * + * @param t A token to push onto the stack (non-null). + */ +private void pushOntoStack(Token t) { + if (t!=null && !stack.isEmpty() && t.equals(stack.peek())) { + System.err.println("ERROR: Token being duplicated: " + t); + Thread.dumpStack(); + System.exit(5); + } + else if (t==null) { + System.err.println("ERROR: null token pushed onto stack"); + Thread.dumpStack(); + System.exit(6); + } + stack.push(t); +} + + + /** + * Decreases the depth in which we're in TypeArguments or TypeParameters. + * + * @see #increaseTypeArgumentsLevel() + * @see #getTypeArgumentsLevel() + */ + public void decreaseTypeArgumentsLevel() { + if (--typeArgLevel<0) { + throw new InternalError("typeArgLevel dipped below 0"); + } + } + + + /** + * Returns an offset into the source being parsed. This offset will be + * tracked if we are parsing code from a Swing JTextComponent. + * + * @param offs The offset. + * @return An object representing the offset. + * @see #setDocument(Document) + */ + public Offset createOffset(final int offs) { + if (doc!=null) { + try { + return new DocumentOffset(doc.createPosition(offs)); + } catch (BadLocationException ble) { // Should never happen + ble.printStackTrace(); + } + } + return new Offset() { + public int getOffset() { + return offs; + } + }; + } + + + private void debugPrintToken(Token t) { + if (DEBUG) { + if (t==null) { + System.out.println("... null"); + } + else { + System.out.println("... " + t); + } + } + } + + + /** + * Returns the current column into the current line. + * + * @return The current column. + * @see #getLine() + */ + public int getColumn() { + return s.getColumn(); + } + + + /** + * Returns the last documentation comment parsed. The "last documentation + * comment" is cleared when this method returns. + * + * @return The last documentation comment parsed, or null + * if there was none. + */ + public String getLastDocComment() { + return s.getLastDocComment(); + } + + + /** + * Returns the current line into the document. + * + * @return The current line. + * @see #getColumn() + */ + public int getLine() { + return s.getLine(); + } + + + /** + * Returns the most recently-lexed token. + * + * @return The token, or null if EOS was reached. + */ + public Token getMostRecentToken() { + return mostRecentToken; + } + + + /** + * Returns the current offset into the document. + * + * @return The offset. + */ + public int getOffset() { + return s.getOffset(); + } + + + /** + * Eats through (possibly nested) paren pairs, e.g.: + *
    (int i=0; i<getFoo(getParam()); i++)
    . + * Blocks nested inside the paren pairs are also skipped. + * + * @throws IOException If an IO error occurs. + * @throws InternalError If the next token is not a '('. + */ + public void eatParenPairs() throws IOException { + + Token t = yylex(); + if (t==null || t.getType()!=TokenTypes.SEPARATOR_LPAREN) { + throw new InternalError("'(' expected, found: " + t); + } + + int blockDepth = 0; + int parenDepth = 1; + + while ((t=yylex())!=null) { + int type = t.getType(); + switch (type) { + case TokenTypes.SEPARATOR_LBRACE: + blockDepth++; + break; + case TokenTypes.SEPARATOR_RBRACE: + blockDepth = Math.max(blockDepth-1, 0); + break; + case TokenTypes.SEPARATOR_LPAREN: + if (blockDepth==0) { + parenDepth++; + } + break; + case TokenTypes.SEPARATOR_RPAREN: + if (blockDepth==0 && --parenDepth == 0) { + return; + } + break; + } + } + + } + + + /** + * Eats all tokens up to (and including) the next token of the specified + * type. This is useful, for example, to eat until the next semicolon. + * + * @param tokenType The type of token to eat through. + * @throws IOException If an IO error occurs. + */ + public void eatThroughNext(int tokenType) throws IOException { + Token t = null; + while ((t=yylex())!=null && t.getType()!=tokenType); + } + + + /** + * Eats all tokens up to (and including) the next token of the specified + * type. This is useful, for example, to eat until the next semicolon. + * + * @param tokenType The type of token to eat through. + * @throws IOException If an IO error occurs. + * @see #eatThroughNextSkippingBlocks(int, int) + * @see #eatThroughNextSkippingBlocksAndStuffInParens(int, int) + */ + public void eatThroughNextSkippingBlocks(int tokenType) throws IOException { + Token t = null; + int blockDepth = 0; + while ((t=yylex())!=null) { + int type = t.getType(); + if (type==TokenTypes.SEPARATOR_LBRACE) { + blockDepth++; + } + else if (type==TokenTypes.SEPARATOR_RBRACE) { + blockDepth--; + } + else if (type==tokenType) { + if (blockDepth<=0) { + return; + } + } + } + } + + + /** + * Eats all tokens up to (and including) the next token of one of the + * specified types. This is useful, for example, to eat until the next + * equal sign or semicolon. + * + * @param tokenType1 The type of token to eat through. + * @param tokenType2 Another type of token to eat through. + * @return The last token read. This will either be one of the two token + * types passed in, or null if the end of the stream + * is reached. + * @throws IOException If an IO error occurs. + * @see #eatThroughNextSkippingBlocksAndStuffInParens(int, int) + */ + public Token eatThroughNextSkippingBlocks(int tokenType1, + int tokenType2) throws IOException { + Token t = null; + int blockDepth = 0; + while ((t=yylex())!=null) { + int type = t.getType(); + if (type==TokenTypes.SEPARATOR_LBRACE) { + blockDepth++; + } + else if (type==TokenTypes.SEPARATOR_RBRACE) { + blockDepth--; + } + else if (type==tokenType1 || type==tokenType2) { + if (blockDepth<=0) { + return t; + } + } + } + return null; + } + + + /** + * Eats all tokens up to (and including) the next token of one of the + * specified types. This is useful, for example, to eat until the next + * equal sign or semicolon. + * + * @param tokenType1 The type of token to eat through. + * @param tokenType2 Another type of token to eat through. + * @return The last token read. This will either be one of the two token + * types passed in, or null if the end of the stream + * is reached. + * @throws IOException If an IO error occurs. + * @see #eatThroughNextSkippingBlocks(int, int) + */ + public Token eatThroughNextSkippingBlocksAndStuffInParens(int tokenType1, + int tokenType2) throws IOException { + + Token t = null; + int blockDepth = 0; + int parenDepth = 0; + + while ((t=yylex())!=null) { + int type = t.getType(); + switch (type) { + case TokenTypes.SEPARATOR_LBRACE: + blockDepth++; + break; + case TokenTypes.SEPARATOR_RBRACE: + blockDepth--; + break; + case TokenTypes.SEPARATOR_LPAREN: + parenDepth++; + break; + case TokenTypes.SEPARATOR_RPAREN: + parenDepth--; + break; + default: + if (type==tokenType1 || type==tokenType2) { + if (blockDepth<=0 && parenDepth<=0) { + return t; + } + } + } + } + + return null; + + } + + + public void eatUntilNext(int type1, int type2) throws IOException { + Token t = null; + while ((t=yylex())!=null) { + int type = t.getType(); + if (type==type1 || type==type2) { + yyPushback(t); + break; + } + } + } + + + public void eatUntilNext(int type1, int type2, int type3) throws IOException { + Token t = null; + while ((t=yylex())!=null) { + int type = t.getType(); + if (type==type1 || type==type2 || type==type3) { + yyPushback(t); + break; + } + } + } + + + /** + * Returns the current TypeArgument/TypeParameter level. + * + * @return The current level. + * @see #increaseTypeArgumentsLevel() + * @see #decreaseTypeArgumentsLevel() + */ + public int getTypeArgumentsLevel() { + return typeArgLevel; + } + + + /** + * Increases the depth in which we're in TypeArguments or TypeParameters. + * + * @see #decreaseTypeArgumentsLevel() + * @see #getTypeArgumentsLevel() + */ + public void increaseTypeArgumentsLevel() { + typeArgLevel++; + } + + +private Stack> resetPositions; +private Stack currentResetTokenStack; +private int currentResetStartOffset; + public void markResetPosition() { + if (s!=null) { // Hack! We should really do something for token-only scanners + if (resetPositions==null) { + resetPositions = new Stack>(); + } + currentResetTokenStack = new Stack(); + resetPositions.push(currentResetTokenStack); + currentResetStartOffset = s.getOffset(); + } + } + public void resetToLastMarkedPosition() { + if (s!=null) { // Hack! We should really do something for token-only scanners + if (currentResetTokenStack==null) { + throw new InternalError("No resetTokenStack!"); + } + // Remove tokens off the standard stack within the "marked" range + while (!stack.isEmpty()) { + Token t = stack.peek(); + if (t.getOffset()>=currentResetStartOffset) { + stack.pop(); + } + else { + break; + } + } + // Add all tokens in the "marked" range to our stack + while (!currentResetTokenStack.isEmpty()) { + Token t = currentResetTokenStack.pop(); + stack.push(t); + } + resetPositions.pop(); // Remote currentResetTokenStack + currentResetTokenStack = resetPositions.isEmpty() ? null : (Stack)resetPositions.peek(); + currentResetStartOffset = -1; + } + } + public void clearResetPosition() { + if (s!=null) { // Hack! We should really do something for token-only scanners + if (currentResetTokenStack==null) { + throw new InternalError("No resetTokenStack!"); + } + resetPositions.pop(); // Remote currentResetTokenStack + currentResetTokenStack = resetPositions.isEmpty() ? null : (Stack)resetPositions.peek(); + currentResetStartOffset = -1; + } + } + + /** + * Sets the Swing Document whose content is being parsed. + * This method should be called if we are parsing code inside a + * JTextComponent, as it will help our parsed code to track + * changes when the document is modified. If we are parsing source from a + * flat file, this method shouldn't be called. + * + * @param doc The document being parsed. + */ + public void setDocument(Document doc) { + this.doc = doc; + } + + + /** + * Skips all bracket pairs ('[' followed by ']') in the stream. + * + * @return The number of bracket pairs skipped. + * @throws IOException If an IO error occurs. + */ + public int skipBracketPairs() throws IOException { + + int count = 0; + + while (yyPeekCheckType()==TokenTypes.SEPARATOR_LBRACKET && + yyPeekCheckType(2)==TokenTypes.SEPARATOR_RBRACKET) { + yylex(); + yylex(); + count++; + } + + return count; + + } + + + /** + * Returns the next token from the input stream. + * + * @return The next token. + * @throws IOException If an IO error occurs. + */ + /* + * NOTE: All other lex'ing methods should call into this one. + */ + public Token yylex() throws IOException { + + Token t = null; + if (stack.isEmpty()) { + t = s!=null ? s.yylex() : null; + } + else { + t = stack.pop(); + } + + // If we have nested TypeArguments ("Set>"), + // Prevent the ">>" from coming across as a single token. + if (typeArgLevel>0 && t!=null && t.isOperator()) { + String lexeme = t.getLexeme(); + if (lexeme.length()>1) { + char ch = lexeme.charAt(0); + if (ch=='<') { + Token rest = null; + switch (t.getType()) { + case TokenTypes.OPERATOR_LTE: + rest = new TokenImpl(Token.OPERATOR_EQUALS, "=", + t.getLine(), t.getColumn()+1, t.getOffset()+1); + break; + case TokenTypes.OPERATOR_LSHIFT: + rest = new TokenImpl(Token.OPERATOR_LT, "<", + t.getLine(), t.getColumn()+1, t.getOffset()+1); + break; + case TokenTypes.OPERATOR_LSHIFT_EQUALS: + rest = new TokenImpl(Token.OPERATOR_LTE, "<=", + t.getLine(), t.getColumn()+1, t.getOffset()+1); + break; + } + stack.push(rest); + t = new TokenImpl(Token.OPERATOR_LT, "<", + t.getLine(), t.getColumn(), t.getOffset()); + } + else if (ch=='>') { + Token rest = null; + switch (t.getType()) { + case TokenTypes.OPERATOR_GTE: + rest = new TokenImpl(Token.OPERATOR_EQUALS, "=", + t.getLine(), t.getColumn()+1, t.getOffset()+1); + break; + case TokenTypes.OPERATOR_RSHIFT: + rest = new TokenImpl(Token.OPERATOR_GT, ">", + t.getLine(), t.getColumn()+1, t.getOffset()+1); + break; + case TokenTypes.OPERATOR_RSHIFT2: + rest = new TokenImpl(Token.OPERATOR_RSHIFT, ">>", + t.getLine(), t.getColumn()+1, t.getOffset()+1); + break; + case TokenTypes.OPERATOR_RSHIFT_EQUALS: + rest = new TokenImpl(Token.OPERATOR_GTE, ">=", + t.getLine(), t.getColumn()+1, t.getOffset()+1); + break; + case TokenTypes.OPERATOR_RSHIFT2_EQUALS: + rest = new TokenImpl(Token.OPERATOR_RSHIFT_EQUALS, ">>=", + t.getLine(), t.getColumn()+1, t.getOffset()+1); + break; + } + stack.push(rest); + t = new TokenImpl(Token.OPERATOR_GT, ">", + t.getLine(), t.getColumn(), t.getOffset()); + } + } + } + + debugPrintToken(t); + if (currentResetTokenStack!=null) { + currentResetTokenStack.push(t); + } + if (t!=null) { // Don't let EOS corrupt most recent token + mostRecentToken = t; + } + return t; + + } + + + /** + * Returns the next token from the input stream, or throws an exception + * if the end of stream is reached. + * + * @param error The error description for the exception if the end of + * stream is reached. + * @return The token. + * @throws IOException If an IO error occurs or the end of stream is + * reached. + */ + public Token yylexNonNull(String error) throws IOException { + Token t = yylex(); + if (t==null) { + throw new EOFException(error); + } + return t; + } + + + /** + * Returns the next token from the input stream, or throws an exception + * if the end of stream is reached or if the token is not of a given + * type. + * + * @param type The type the token must be. + * @param error The error description for the exception if the end of + * stream is reached, or if the token is of an unexpected type. + * @return The token. + * @throws IOException If an IO error occurs or the end of stream is + * reached, or if the token is of the wrong type. + */ + public Token yylexNonNull(int type, String error) throws IOException { + return yylexNonNull(type, -1, error); + } + + + /** + * Returns the next token from the input stream, or throws an exception + * if the end of stream is reached or if the token is not of two given + * types. + * + * @param type1 One type the token can be. + * @param type2 Another type the token can be, or -1 if we + * should only check against type1. + * @param error The error description for the exception if the end of + * stream is reached, or if the token is of an unexpected type. + * @return The token. + * @throws IOException If an IO error occurs or the end of stream is + * reached, or if the token is of a wrong type. + */ + public Token yylexNonNull(int type1, int type2, String error) + throws IOException { + return yylexNonNull(type1, type2, -1, error); + } + + + /** + * Returns the next token from the input stream, or throws an exception + * if the end of stream is reached or if the token is not of three given + * types. + * + * @param type1 One type the token can be. + * @param type2 Another type the token can be, or -1 if we + * should only check against type1. + * @param type3 Another type the token can be, or -1 if we + * should only check against type1 and type2. + * @param error The error description for the exception if the end of + * stream is reached, or if the token is of an unexpected type. + * @return The token. + * @throws IOException If an IO error occurs or the end of stream is + * reached, or if the token is of a wrong type. + */ + public Token yylexNonNull(int type1, int type2, int type3, String error) + throws IOException { + Token t = yylex(); + if (t==null) { + throw new IOException(error); + } + if (t.getType()!=type1 && (type2==-1 || t.getType()!=type2) && + (type3==-1 || t.getType()!=type3)) { + throw new IOException(error + ", found '" + t.getLexeme() + "'"); + } + return t; + } + + + /** + * Returns the next token, but does not take it off of the stream. This + * is useful for lookahead. + * + * @return The next token. + * @throws IOException If an IO error occurs. + */ + public Token yyPeek() throws IOException { + Token t = yylex(); + if (t!=null) { + pushOntoStack(t); + } + return t; + } + + + /** + * Returns the depth-th token, but does not anything off of the + * stream. This is useful for lookahead. + * + * @param depth The token to peek at, from 1 forward. + * @return The token, or null if that token index is past the + * end of the stream. + * @throws IOException If an IO error occurs. + */ + public Token yyPeek(int depth) throws IOException { + if (depth<1) { + throw new IllegalArgumentException("depth must be >= 1"); + } + Stack read = new Stack(); + for (int i=0; i-1 if the end of stream + * has been reached. + * @throws IOException If an IO error occurs. + */ + public int yyPeekCheckType() throws IOException { + Token t = yyPeek(); + return t!=null ? t.getType() : -1; + } + + + /** + * Peeks at and returns the type of the specified token on the stream. + * + * @param index The index of the token to retrieve. + * @return The type of the token, or -1 if the end of stream + * was reached first. + * @throws IOException If an IO error occurs. + */ + public int yyPeekCheckType(int index) throws IOException { + Token t = yyPeek(index); + return t!=null ? t.getType() : -1; + } + + + /** + * Returns the next token, but does not take it off of the stream. This + * is useful for lookahead. + * + * @return The next token. + * @throws IOException If an IO error occurs. + */ + public Token yyPeekNonNull(String error) throws IOException { + Token t = yyPeek(); + if (t==null) { + throw new IOException(error); + } + return t; + } + + + /** + * Returns the next token, but does not take it off of the stream. This + * is useful for lookahead. + * + * @param type The type the token must be. + * @return The next token. + * @throws IOException If an IO error occurs, or if EOS is reached, or + * if the token is not of the specified type. + */ + public Token yyPeekNonNull(int type, String error) throws IOException { + return yyPeekNonNull(type, -1, error); + } + + + /** + * Returns the next token, but does not take it off of the stream. This + * is useful for lookahead. + * + * @param type1 One of the two types the token must be. + * @param type2 The other of the two types the token must be. + * @return The next token. + * @throws IOException If an IO error occurs, or if EOS is reached, or + * if the token is not of the specified type. + */ + public Token yyPeekNonNull(int type1, int type2, String error) + throws IOException { + return yyPeekNonNull(type1, type2, -1, error); + } + + + /** + * Returns the next token, but does not take it off of the stream. This + * is useful for lookahead. + * + * @param type1 One of the three types the token must be. + * @param type2 Another of the three types the token must be. + * @param type3 The third of the types the token must be. + * @return The next token. + * @throws IOException If an IO error occurs, or if EOS is reached, or + * if the token is not of the specified type. + */ + public Token yyPeekNonNull(int type1, int type2, int type3, String error) + throws IOException { + Token t = yyPeek(); + if (t==null) { + throw new IOException(error); + } + if (t.getType()!=type1 && (type2==-1 || t.getType()!=type2) && + (type3==-1 || t.getType()!=type3)) { + throw new IOException(error + ", found '" + t.getLexeme() + "'"); + } + return t; + } + + + /** + * Pushes a token back onto the stream. + * + * @param t The token. + */ + public void yyPushback(Token t) { + if (t!=null) { + pushOntoStack(t); + } + } + + + private class DocumentOffset implements Offset { + + public Position pos; + + public DocumentOffset(Position pos) { + this.pos = pos; + } + + public int getOffset() { + return pos.getOffset(); + } + + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/SourceCodeScanner.flex b/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/SourceCodeScanner.flex new file mode 100644 index 00000000..c7075829 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/SourceCodeScanner.flex @@ -0,0 +1,393 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.java.rjc.lexer; + + +/** + * Scanner for the Java programming language.

    + * + * @author Robert Futrell + * @version 0.1 + */ +%% + +%class SourceCodeScanner +%implements org.fife.rsta.ac.java.rjc.lexer.TokenTypes +%unicode +%line +%column +%char +%type org.fife.rsta.ac.java.rjc.lexer.Token + + +%{ + + /** + * Whether comments should be returned as tokens. + */ + private boolean returnComments; + + /** + * Whether whitespace should be returned as tokens. + */ + private boolean returnWhitespace; + + /** + * Whether the last documentation comment parsed should be kept. + */ + private boolean keepLastDocComment; + + /** + * The last documentation comment parsed, if that feature is enabled. + */ + private String lastDocComment; + + + private Token createToken(int type) { + return createToken(type, false); + } + + + private Token createToken(int type, boolean invalid) { + return new TokenImpl(type, yytext(), yyline, yycolumn, yychar, invalid); + } + + + /** + * Returns the current column into the current line. + * + * @return The current column. + */ + public int getColumn() { + return yycolumn; + } + + + /** + * Returns the last documentation comment parsed, if this feature is + * enabled. + * + * @return The last documentation comment parsed, or null + * if the feature is disabled. + * @see #setKeepLastDocComment(boolean) + */ + public String getLastDocComment() { + return lastDocComment; + } + + + /** + * Returns the current line into the document. + * + * @return The current line. + */ + public int getLine() { + return yyline; + } + + + /** + * Returns the current offset into the document. + * + * @return The offset. + */ + public int getOffset() { + return yychar; + } + + + /** + * Returns whether comments are returned as tokens. + * + * @return Whether comments are returned as tokens. + * @see #getReturnWhitespace() + */ + public boolean getReturnComments() { + return returnComments; + } + + + /** + * Returns whether whitespace is returned as tokens. + * + * @return Whether whitespace is returned as tokens. + * @see #getReturnComments() + */ + public boolean getReturnWhitespace() { + return returnWhitespace; + } + + + /** + * Sets whether the last documentation comment should be kept. + * + * @param keep Whether to keep the last documentation comment. + * @see #getLastDocComment() + */ + public void setKeepLastDocComment(boolean keep) { + keepLastDocComment = keep; + } + + + /** + * Sets whether comments are returned as tokens. + * + * @param returnComments Whether comments should be returned as tokens. + * @see #getReturnComments() + * @see #setReturnWhitespace(boolean) + */ + public void setReturnComments(boolean returnComments) { + this.returnComments = returnComments; + } + + + /** + * Sets whether whitespace is returned as tokens. + * + * @param returnWhitespace Whether whitespace should be returned as tokens. + * @see #getReturnWhitespace() + * @see #setReturnComments(boolean) + */ + public void setReturnWhitespace(boolean returnWhitespace) { + this.returnWhitespace = returnWhitespace; + } + + +%} + +/* JLS 3.3 - Unicode Escapes */ +UnicodeInputCharacter = ({UnicodeEscape}|{RawInputCharacter}) +UnicodeEscape = ([\\]{UnicodeMarker}{HexDigit}{4}) +UnicodeMarker = ("u"|{UnicodeMarker}"u") +RawInputCharacter = (.) + +/* JLS 3.4 - Line Terminators */ +LineTerminator = (\r|\n|\r\n) +// JFlex has some trouble compiling InputCharacter... +//InputCharacter = ({UnicodeInputCharacter}|[^\r\n]) +InputCharacter = ([\\][u]+{HexDigit}{4}|[^\r\n]) + +/* JLS 3.6 - White Space */ +WhiteSpace = (([ \t\f]|{LineTerminator})+) + +/* JLS 3.7 - Comments (made non-recursive for JFlex) */ +DocumentationComment = ("/*" "*"+ [^/*] ~"*/") +Comment = ({TraditionalComment}|{EndOfLineComment}) +TraditionalComment = ("/*" [^*] ~"*/" | "/*" "*"+ "/") +EndOfLineComment = ("//" {CharactersInLine}?) +CharactersInLine = ({InputCharacter}+) + +/* JLS 3.8 - Identifiers (made non-recursive for JFlex) */ +Identifier = ({IdentifierChars}) /* but not Keyword, BooleanLiteral, NullLiteral */ +IdentifierChars = ({JavaLetter}{JavaLetterOrDigit}*) +JavaLetter = ([:jletter:]) +JavaLetterOrDigit = ([:jletterdigit:]) + +/* JLS 3.10.1 - Integer Literals */ +IntegerLiteral = ({DecimalIntegerLiteral}|{HexIntegerLiteral}|{OctalIntegerLiteral}) +DecimalIntegerLiteral = ({DecimalNumeral}{IntegerTypeSuffix}?) +HexIntegerLiteral = ({HexNumeral}{IntegerTypeSuffix}?) +OctalIntegerLiteral = ({OctalNumeral}{IntegerTypeSuffix}?) +IntegerTypeSuffix = ([lL]) +DecimalNumeral = ("0"|{NonZeroDigit}{Digits}?) +Digits = ({Digit}+) +Digit = ("0"|{NonZeroDigit}) +NonZeroDigit = ([1-9]) +HexNumeral = ("0"[xX]{HexDigits}) +HexDigits = ({HexDigit}+) +HexDigit = ([0-9a-fA-F]) +OctalNumeral = ("0"{OctalDigits}) +OctalDigits = ({OctalDigit}+) +OctalDigit = ([0-7]) + +/* JLS 3.10.2 - Floating Point Literals */ +/* TODO*/ +FloatingPointLiteral = ([0-9]+[\.][0-9]+[fF]) + +/* JLS 3.10.3 - Boolean Literals */ +BooleanLiteral = ("true"|"false") + +/* JLS 3.10.4 - Character Literals */ +CharacterLiteral = ([\']({SingleCharacter}|{EscapeSequence})[\']) +SingleCharacter = ([\\][u]+{HexDigit}{4}|[^\r\n\'\\]) +InvalidCharLiteral = ([\'][^\']*[\']?) + +/* JLS 3.10.5 - String Literals */ +StringLiteral = ([\"]{StringCharacters}*[\"]) +StringCharacters = ({StringCharacter}+) +StringCharacter = ([\\][u]+{HexDigit}{4}|[^\r\n\"\\]|{EscapeSequence}) +//StringCharacter = ([^\r\n\"\\]|{EscapeSequence}) +InvalidStringLiteral = ([\"][^\"]*[\"]?) + +/* JLS 3.10.6 - Escape Sequences for Character and String Literals */ +EscapeSequence = ([\\][btnfr\"\'\\]|{OctalEscape}) +OctalEscape = ([\\]({OctalDigit}{OctalDigit}?|{ZeroToThree}{OctalDigit}{OctalDigit})) +OctalDigit = ([0-7]) +ZeroToThree = ([0-3]) + +/* JLS 3.10.7 - The Null Literal */ +NullLiteral = ("null") + +/* ??? - Stuff not in JLS */ +AnnotationStart = ([\@]) +Elipsis = ("...") + + +%% + + { + + {WhiteSpace} { + if (returnWhitespace) { + return createToken(Token.WHITESPACE); + } + } + + {DocumentationComment} { + if (keepLastDocComment) { + lastDocComment = yytext(); + } + if (returnComments) { + return createToken(Token.DOC_COMMENT); + } + } + + {Comment} { + if (returnComments) { + return createToken(Token.COMMENT); + } + } + + /* Keywords */ + "abstract" { return createToken(KEYWORD_ABSTRACT); } + "assert" { return createToken(KEYWORD_ASSERT); } + "break" { return createToken(KEYWORD_BREAK); } + "case" { return createToken(KEYWORD_CASE); } + "catch" { return createToken(KEYWORD_CATCH); } + "class" { return createToken(KEYWORD_CLASS); } + "const" { return createToken(KEYWORD_CONST); } + "continue" { return createToken(KEYWORD_CONTINUE); } + "default" { return createToken(KEYWORD_DEFAULT); } + "do" { return createToken(KEYWORD_DO); } + "else" { return createToken(KEYWORD_ELSE); } + "enum" { return createToken(KEYWORD_ENUM); } + "extends" { return createToken(KEYWORD_EXTENDS); } + "final" { return createToken(KEYWORD_FINAL); } + "finally" { return createToken(KEYWORD_FINALLY); } + "for" { return createToken(KEYWORD_FOR); } + "goto" { return createToken(KEYWORD_GOTO); } + "if" { return createToken(KEYWORD_IF); } + "implements" { return createToken(KEYWORD_IMPLEMENTS); } + "import" { return createToken(KEYWORD_IMPORT); } + "instanceof" { return createToken(KEYWORD_INSTANCEOF); } + "interface" { return createToken(KEYWORD_INTERFACE); } + "native" { return createToken(KEYWORD_NATIVE); } + "new" { return createToken(KEYWORD_NEW); } + "package" { return createToken(KEYWORD_PACKAGE); } + "private" { return createToken(KEYWORD_PRIVATE); } + "protected" { return createToken(KEYWORD_PROTECTED); } + "public" { return createToken(KEYWORD_PUBLIC); } + "return" { return createToken(KEYWORD_RETURN); } + "static" { return createToken(KEYWORD_STATIC); } + "strictfp" { return createToken(KEYWORD_STRICTFP); } + "super" { return createToken(KEYWORD_SUPER); } + "switch" { return createToken(KEYWORD_SWITCH); } + "synchronized" { return createToken(KEYWORD_SYNCHRONIZED); } + "this" { return createToken(KEYWORD_THIS); } + "throw" { return createToken(KEYWORD_THROW); } + "throws" { return createToken(KEYWORD_THROWS); } + "transient" { return createToken(KEYWORD_TRANSIENT); } + "try" { return createToken(KEYWORD_TRY); } + "void" { return createToken(KEYWORD_VOID); } + "volatile" { return createToken(KEYWORD_VOLATILE); } + "while" { return createToken(KEYWORD_WHILE); } + + /* Data types */ + "boolean" { return createToken(KEYWORD_BOOLEAN); } + "byte" { return createToken(KEYWORD_BYTE); } + "char" { return createToken(KEYWORD_CHAR); } + "double" { return createToken(KEYWORD_DOUBLE); } + "float" { return createToken(KEYWORD_FLOAT); } + "int" { return createToken(KEYWORD_INT); } + "long" { return createToken(KEYWORD_LONG); } + "short" { return createToken(KEYWORD_SHORT); } + + /* Literals */ + {IntegerLiteral} { return createToken(LITERAL_INT); } + {FloatingPointLiteral} { return createToken(LITERAL_FP); } + {BooleanLiteral} { return createToken(LITERAL_BOOLEAN); } + {CharacterLiteral} { return createToken(LITERAL_CHAR); } + {StringLiteral} { return createToken(LITERAL_STRING); } + {NullLiteral} { return createToken(LITERAL_NULL); } + {InvalidCharLiteral} { return createToken(LITERAL_CHAR, true); } + {InvalidStringLiteral} { return createToken(LITERAL_STRING, true); } + + {Identifier} { return createToken(IDENTIFIER); } + + {AnnotationStart} { return createToken(ANNOTATION_START); } + + {Elipsis} { return createToken(ELIPSIS); } + + /* Separators (JLS 3.11) */ + "(" { return createToken(SEPARATOR_LPAREN); } + ")" { return createToken(SEPARATOR_RPAREN); } + "{" { return createToken(SEPARATOR_LBRACE); } + "}" { return createToken(SEPARATOR_RBRACE); } + "[" { return createToken(SEPARATOR_LBRACKET); } + "]" { return createToken(SEPARATOR_RBRACKET); } + ";" { return createToken(SEPARATOR_SEMICOLON); } + "," { return createToken(SEPARATOR_COMMA); } + "." { return createToken(SEPARATOR_DOT); } + + /* Operators (JLS 3.12) */ + "=" { return createToken(OPERATOR_EQUALS); } + ">" { return createToken(OPERATOR_GT); } + "<" { return createToken(OPERATOR_LT); } + "!" { return createToken(OPERATOR_LOGICAL_NOT); } + "~" { return createToken(OPERATOR_BITWISE_NOT); } + "?" { return createToken(OPERATOR_QUESTION); } + ":" { return createToken(OPERATOR_COLON); } + "==" { return createToken(OPERATOR_EQUALS_EQUALS); } + "<=" { return createToken(OPERATOR_LTE); } + ">=" { return createToken(OPERATOR_GTE); } + "!=" { return createToken(OPERATOR_NE); } + "&&" { return createToken(OPERATOR_LOGICAL_AND); } + "||" { return createToken(OPERATOR_LOGICAL_OR); } + "++" { return createToken(OPERATOR_INCREMENT); } + "--" { return createToken(OPERATOR_DECREMENT); } + "+" { return createToken(OPERATOR_PLUS); } + "-" { return createToken(OPERATOR_MINUS); } + "*" { return createToken(OPERATOR_TIMES); } + "/" { return createToken(OPERATOR_DIVIDE); } + "&" { return createToken(OPERATOR_BITWISE_AND); } + "|" { return createToken(OPERATOR_BITWISE_OR); } + "^" { return createToken(OPERATOR_BITWISE_XOR); } + "%" { return createToken(OPERATOR_MOD); } + "<<" { return createToken(OPERATOR_LSHIFT); } + ">>" { return createToken(OPERATOR_RSHIFT); } + ">>>" { return createToken(OPERATOR_RSHIFT2); } + "+=" { return createToken(OPERATOR_PLUS_EQUALS); } + "-=" { return createToken(OPERATOR_MINUS_EQUALS); } + "*=" { return createToken(OPERATOR_TIMES_EQUALS); } + "/=" { return createToken(OPERATOR_DIVIDE_EQUALS); } + "&=" { return createToken(OPERATOR_BITWISE_AND_EQUALS); } + "|=" { return createToken(OPERATOR_BITWISE_OR_EQUALS); } + "^=" { return createToken(OPERATOR_BITWISE_XOR_EQUALS); } + "%=" { return createToken(OPERATOR_MOD_EQUALS); } + "<<=" { return createToken(OPERATOR_LSHIFT_EQUALS); } + ">>=" { return createToken(OPERATOR_RSHIFT_EQUALS); } + ">>>=" { return createToken(OPERATOR_RSHIFT2_EQUALS); } + + + /* Unhandled stuff. */ + . { return createToken(IDENTIFIER, true); } + +} diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/SourceCodeScanner.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/SourceCodeScanner.java new file mode 100644 index 00000000..f8a5f1ae --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/SourceCodeScanner.java @@ -0,0 +1,1663 @@ +/* The following code was generated by JFlex 1.4.1 on 3/31/10 5:27 PM */ + +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.rjc.lexer; + + +/** + * Scanner for the Java programming language.

    + * + * @author Robert Futrell + * @version 0.1 + */ + +class SourceCodeScanner implements org.fife.rsta.ac.bsh.rjc.lexer.TokenTypes { + + /** This character denotes the end of file */ + public static final int YYEOF = -1; + + /** initial size of the lookahead buffer */ + private static final int ZZ_BUFFERSIZE = 16384; + + /** lexical states */ + public static final int YYINITIAL = 0; + + /** + * Translates characters to character classes + */ + private static final String ZZ_CMAP_PACKED = + "\11\10\1\4\1\3\1\0\1\4\1\3\16\10\4\0\1\4\1\67"+ + "\1\31\1\0\1\7\1\100\1\73\1\30\1\54\1\55\1\6\1\75"+ + "\1\63\1\76\1\17\1\5\1\12\3\34\4\16\2\13\1\72\1\62"+ + "\1\66\1\64\1\65\1\71\1\35\5\15\1\20\5\7\1\11\13\7"+ + "\1\14\2\7\1\60\1\1\1\61\1\77\1\7\1\0\1\25\1\33"+ + "\1\36\1\43\1\23\1\24\1\47\1\40\1\42\1\7\1\37\1\26"+ + "\1\44\1\32\1\41\1\50\1\7\1\22\1\27\1\21\1\2\1\51"+ + "\1\52\1\45\1\46\1\53\1\56\1\74\1\57\1\70\41\10\2\0"+ + "\4\7\4\0\1\7\2\0\1\10\7\0\1\7\4\0\1\7\5\0"+ + "\27\7\1\0\37\7\1\0\u013f\7\31\0\162\7\4\0\14\7\16\0"+ + "\5\7\11\0\1\7\21\0\130\10\5\0\23\10\12\0\1\7\13\0"+ + "\1\7\1\0\3\7\1\0\1\7\1\0\24\7\1\0\54\7\1\0"+ + "\46\7\1\0\5\7\4\0\202\7\1\0\4\10\3\0\105\7\1\0"+ + "\46\7\2\0\2\7\6\0\20\7\41\0\46\7\2\0\1\7\7\0"+ + "\47\7\11\0\21\10\1\0\27\10\1\0\3\10\1\0\1\10\1\0"+ + "\2\10\1\0\1\10\13\0\33\7\5\0\3\7\15\0\4\10\14\0"+ + "\6\10\13\0\32\7\5\0\13\7\16\10\7\0\12\10\4\0\2\7"+ + "\1\10\143\7\1\0\1\7\10\10\1\0\6\10\2\7\2\10\1\0"+ + "\4\10\2\7\12\10\3\7\2\0\1\7\17\0\1\10\1\7\1\10"+ + "\36\7\33\10\2\0\3\7\60\0\46\7\13\10\1\7\u014f\0\3\10"+ + "\66\7\2\0\1\10\1\7\20\10\2\0\1\7\4\10\3\0\12\7"+ + "\2\10\2\0\12\10\21\0\3\10\1\0\10\7\2\0\2\7\2\0"+ + "\26\7\1\0\7\7\1\0\1\7\3\0\4\7\2\0\1\10\1\7"+ + "\7\10\2\0\2\10\2\0\3\10\11\0\1\10\4\0\2\7\1\0"+ + "\3\7\2\10\2\0\12\10\4\7\15\0\3\10\1\0\6\7\4\0"+ + "\2\7\2\0\26\7\1\0\7\7\1\0\2\7\1\0\2\7\1\0"+ + "\2\7\2\0\1\10\1\0\5\10\4\0\2\10\2\0\3\10\13\0"+ + "\4\7\1\0\1\7\7\0\14\10\3\7\14\0\3\10\1\0\11\7"+ + "\1\0\3\7\1\0\26\7\1\0\7\7\1\0\2\7\1\0\5\7"+ + "\2\0\1\10\1\7\10\10\1\0\3\10\1\0\3\10\2\0\1\7"+ + "\17\0\2\7\2\10\2\0\12\10\1\0\1\7\17\0\3\10\1\0"+ + "\10\7\2\0\2\7\2\0\26\7\1\0\7\7\1\0\2\7\1\0"+ + "\5\7\2\0\1\10\1\7\6\10\3\0\2\10\2\0\3\10\10\0"+ + "\2\10\4\0\2\7\1\0\3\7\4\0\12\10\1\0\1\7\20\0"+ + "\1\10\1\7\1\0\6\7\3\0\3\7\1\0\4\7\3\0\2\7"+ + "\1\0\1\7\1\0\2\7\3\0\2\7\3\0\3\7\3\0\10\7"+ + "\1\0\3\7\4\0\5\10\3\0\3\10\1\0\4\10\11\0\1\10"+ + "\17\0\11\10\11\0\1\7\7\0\3\10\1\0\10\7\1\0\3\7"+ + "\1\0\27\7\1\0\12\7\1\0\5\7\4\0\7\10\1\0\3\10"+ + "\1\0\4\10\7\0\2\10\11\0\2\7\4\0\12\10\22\0\2\10"+ + "\1\0\10\7\1\0\3\7\1\0\27\7\1\0\12\7\1\0\5\7"+ + "\2\0\1\10\1\7\7\10\1\0\3\10\1\0\4\10\7\0\2\10"+ + "\7\0\1\7\1\0\2\7\4\0\12\10\22\0\2\10\1\0\10\7"+ + "\1\0\3\7\1\0\27\7\1\0\20\7\4\0\6\10\2\0\3\10"+ + "\1\0\4\10\11\0\1\10\10\0\2\7\4\0\12\10\22\0\2\10"+ + "\1\0\22\7\3\0\30\7\1\0\11\7\1\0\1\7\2\0\7\7"+ + "\3\0\1\10\4\0\6\10\1\0\1\10\1\0\10\10\22\0\2\10"+ + "\15\0\60\7\1\10\2\7\7\10\4\0\10\7\10\10\1\0\12\10"+ + "\47\0\2\7\1\0\1\7\2\0\2\7\1\0\1\7\2\0\1\7"+ + "\6\0\4\7\1\0\7\7\1\0\3\7\1\0\1\7\1\0\1\7"+ + "\2\0\2\7\1\0\4\7\1\10\2\7\6\10\1\0\2\10\1\7"+ + "\2\0\5\7\1\0\1\7\1\0\6\10\2\0\12\10\2\0\2\7"+ + "\42\0\1\7\27\0\2\10\6\0\12\10\13\0\1\10\1\0\1\10"+ + "\1\0\1\10\4\0\2\10\10\7\1\0\42\7\6\0\24\10\1\0"+ + "\2\10\4\7\4\0\10\10\1\0\44\10\11\0\1\10\71\0\42\7"+ + "\1\0\5\7\1\0\2\7\1\0\7\10\3\0\4\10\6\0\12\10"+ + "\6\0\6\7\4\10\106\0\46\7\12\0\51\7\7\0\132\7\5\0"+ + "\104\7\5\0\122\7\6\0\7\7\1\0\77\7\1\0\1\7\1\0"+ + "\4\7\2\0\7\7\1\0\1\7\1\0\4\7\2\0\47\7\1\0"+ + "\1\7\1\0\4\7\2\0\37\7\1\0\1\7\1\0\4\7\2\0"+ + "\7\7\1\0\1\7\1\0\4\7\2\0\7\7\1\0\7\7\1\0"+ + "\27\7\1\0\37\7\1\0\1\7\1\0\4\7\2\0\7\7\1\0"+ + "\47\7\1\0\23\7\16\0\11\10\56\0\125\7\14\0\u026c\7\2\0"+ + "\10\7\12\0\32\7\5\0\113\7\3\0\3\7\17\0\15\7\1\0"+ + "\4\7\3\10\13\0\22\7\3\10\13\0\22\7\2\10\14\0\15\7"+ + "\1\0\3\7\1\0\2\10\14\0\64\7\40\10\3\0\1\7\3\0"+ + "\2\7\1\10\2\0\12\10\41\0\3\10\2\0\12\10\6\0\130\7"+ + "\10\0\51\7\1\10\126\0\35\7\3\0\14\10\4\0\14\10\12\0"+ + "\12\10\36\7\2\0\5\7\u038b\0\154\7\224\0\234\7\4\0\132\7"+ + "\6\0\26\7\2\0\6\7\2\0\46\7\2\0\6\7\2\0\10\7"+ + "\1\0\1\7\1\0\1\7\1\0\1\7\1\0\37\7\2\0\65\7"+ + "\1\0\7\7\1\0\1\7\3\0\3\7\1\0\7\7\3\0\4\7"+ + "\2\0\6\7\4\0\15\7\5\0\3\7\1\0\7\7\17\0\4\10"+ + "\32\0\5\10\20\0\2\7\23\0\1\7\13\0\4\10\6\0\6\10"+ + "\1\0\1\7\15\0\1\7\40\0\22\7\36\0\15\10\4\0\1\10"+ + "\3\0\6\10\27\0\1\7\4\0\1\7\2\0\12\7\1\0\1\7"+ + "\3\0\5\7\6\0\1\7\1\0\1\7\1\0\1\7\1\0\4\7"+ + "\1\0\3\7\1\0\7\7\3\0\3\7\5\0\5\7\26\0\44\7"+ + "\u0e81\0\3\7\31\0\11\7\6\10\1\0\5\7\2\0\5\7\4\0"+ + "\126\7\2\0\2\10\2\0\3\7\1\0\137\7\5\0\50\7\4\0"+ + "\136\7\21\0\30\7\70\0\20\7\u0200\0\u19b6\7\112\0\u51a6\7\132\0"+ + "\u048d\7\u0773\0\u2ba4\7\u215c\0\u012e\7\2\0\73\7\225\0\7\7\14\0"+ + "\5\7\5\0\1\7\1\10\12\7\1\0\15\7\1\0\5\7\1\0"+ + "\1\7\1\0\2\7\1\0\2\7\1\0\154\7\41\0\u016b\7\22\0"+ + "\100\7\2\0\66\7\50\0\15\7\3\0\20\10\20\0\4\10\17\0"+ + "\2\7\30\0\3\7\31\0\1\7\6\0\5\7\1\0\207\7\2\0"+ + "\1\10\4\0\1\7\13\0\12\10\7\0\32\7\4\0\1\7\1\0"+ + "\32\7\12\0\132\7\3\0\6\7\2\0\6\7\2\0\6\7\2\0"+ + "\3\7\3\0\2\7\3\0\2\7\22\0\3\10\4\0"; + + /** + * Translates characters to character classes + */ + private static final char [] ZZ_CMAP = zzUnpackCMap(ZZ_CMAP_PACKED); + + /** + * Translates DFA states to action switch labels. + */ + private static final int [] ZZ_ACTION = zzUnpackAction(); + + private static final String ZZ_ACTION_PACKED_0 = + "\1\0\1\1\1\2\1\3\1\4\1\5\2\6\1\7"+ + "\7\2\1\10\1\11\2\2\1\12\7\2\1\13\1\14"+ + "\1\15\1\16\1\17\1\20\1\21\1\22\1\23\1\24"+ + "\1\25\1\26\1\27\1\30\1\31\1\32\1\33\1\34"+ + "\1\35\1\36\1\37\1\40\1\0\1\41\1\42\2\6"+ + "\4\0\22\2\4\10\2\11\1\43\12\2\1\44\3\2"+ + "\1\45\6\2\1\46\1\47\1\50\1\51\1\52\1\53"+ + "\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63"+ + "\1\64\1\65\2\0\1\6\1\0\1\66\2\2\1\67"+ + "\10\2\1\70\12\2\1\71\4\10\3\11\1\2\1\72"+ + "\11\2\1\73\14\2\1\74\1\75\1\76\2\0\1\40"+ + "\1\77\1\100\2\2\1\101\1\2\1\102\1\103\5\2"+ + "\1\104\6\2\1\10\1\11\2\0\1\105\3\2\1\106"+ + "\1\2\1\107\1\2\1\110\10\2\1\111\5\2\1\112"+ + "\1\2\1\113\1\0\1\2\1\114\2\2\1\115\1\116"+ + "\2\2\1\117\2\2\1\120\2\2\1\10\1\11\1\0"+ + "\1\2\1\121\1\2\1\122\1\123\1\2\1\124\13\2"+ + "\1\125\1\126\1\2\1\127\1\130\2\2\1\131\2\2"+ + "\1\132\1\2\1\133\1\10\1\11\1\0\1\134\5\2"+ + "\1\135\1\2\1\136\1\137\5\2\1\140\1\141\3\2"+ + "\1\0\1\142\4\2\1\143\1\2\1\144\1\145\2\2"+ + "\1\146\1\147\1\2\1\0\1\150\4\2\1\151\1\152"+ + "\1\2\1\153\2\2\1\154\1\2\1\155\1\156\1\2"+ + "\1\157"; + + private static int [] zzUnpackAction() { + int [] result = new int[341]; + int offset = 0; + offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackAction(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); + } + return j; + } + + + /** + * Translates a state to a row index in the transition table + */ + private static final int [] ZZ_ROWMAP = zzUnpackRowMap(); + + private static final String ZZ_ROWMAP_PACKED_0 = + "\0\0\0\101\0\202\0\303\0\u0104\0\u0145\0\u0186\0\u01c7"+ + "\0\u0208\0\u0249\0\u028a\0\u02cb\0\u030c\0\u034d\0\u038e\0\u03cf"+ + "\0\u0410\0\u0451\0\u0492\0\u04d3\0\101\0\u0514\0\u0555\0\u0596"+ + "\0\u05d7\0\u0618\0\u0659\0\u069a\0\101\0\101\0\101\0\101"+ + "\0\101\0\101\0\101\0\101\0\u06db\0\u071c\0\u075d\0\u079e"+ + "\0\101\0\101\0\101\0\u07df\0\u0820\0\u0861\0\u08a2\0\u08e3"+ + "\0\u0924\0\u0965\0\u09a6\0\101\0\101\0\101\0\u09e7\0\u0a28"+ + "\0\u0a69\0\u0aaa\0\u0aeb\0\u0b2c\0\u0b6d\0\u0bae\0\u0bef\0\u0c30"+ + "\0\u0c71\0\u0cb2\0\u0cf3\0\u0d34\0\u0d75\0\u0db6\0\u0df7\0\u0e38"+ + "\0\u0e79\0\u0eba\0\u0efb\0\u0f3c\0\u0f7d\0\u0fbe\0\u0fff\0\u1040"+ + "\0\101\0\u1081\0\u10c2\0\101\0\u1103\0\u1144\0\u1185\0\u11c6"+ + "\0\u1207\0\u1248\0\u1289\0\u12ca\0\u130b\0\u134c\0\202\0\u138d"+ + "\0\u13ce\0\u140f\0\u1450\0\u1491\0\u14d2\0\u1513\0\u1554\0\u1595"+ + "\0\u15d6\0\101\0\101\0\u1617\0\101\0\u1658\0\101\0\101"+ + "\0\101\0\101\0\101\0\101\0\101\0\101\0\101\0\101"+ + "\0\101\0\u1699\0\u16da\0\u171b\0\u175c\0\101\0\u179d\0\u17de"+ + "\0\202\0\u181f\0\u1860\0\u18a1\0\u18e2\0\u1923\0\u1964\0\u19a5"+ + "\0\u19e6\0\202\0\u1a27\0\u1a68\0\u1aa9\0\u1aea\0\u1b2b\0\u1b6c"+ + "\0\u1bad\0\u1bee\0\u1c2f\0\u1c70\0\101\0\u1cb1\0\u1cf2\0\u1d33"+ + "\0\u1d74\0\u1db5\0\u1df6\0\101\0\u1e37\0\202\0\u1e78\0\u1eb9"+ + "\0\u1efa\0\u1f3b\0\u1f7c\0\u1fbd\0\u1ffe\0\u203f\0\u2080\0\u20c1"+ + "\0\u2102\0\u2143\0\u2184\0\u21c5\0\u2206\0\u2247\0\u2288\0\u22c9"+ + "\0\u230a\0\u234b\0\u238c\0\u23cd\0\101\0\u240e\0\101\0\u244f"+ + "\0\u2490\0\101\0\101\0\202\0\u24d1\0\u2512\0\202\0\u2553"+ + "\0\202\0\202\0\u2594\0\u25d5\0\u2616\0\u2657\0\u2698\0\202"+ + "\0\u26d9\0\u271a\0\u275b\0\u279c\0\u27dd\0\u281e\0\u285f\0\u28a0"+ + "\0\u1df6\0\u28e1\0\202\0\u2922\0\u2963\0\u29a4\0\202\0\u29e5"+ + "\0\202\0\u2a26\0\202\0\u2a67\0\u2aa8\0\u2ae9\0\u2b2a\0\u2b6b"+ + "\0\u2bac\0\u2bed\0\u2c2e\0\202\0\u2c6f\0\u2cb0\0\u2cf1\0\u2d32"+ + "\0\u2d73\0\202\0\u2db4\0\101\0\u2df5\0\u2e36\0\u2e77\0\u2eb8"+ + "\0\u2ef9\0\202\0\u2f3a\0\u2f7b\0\u2fbc\0\202\0\u2ffd\0\u303e"+ + "\0\202\0\u307f\0\u30c0\0\u3101\0\u3142\0\u3183\0\u31c4\0\202"+ + "\0\u3205\0\202\0\202\0\u3246\0\202\0\u3287\0\u32c8\0\u3309"+ + "\0\u334a\0\u338b\0\u33cc\0\u340d\0\u344e\0\u348f\0\u34d0\0\u3511"+ + "\0\202\0\101\0\u3552\0\202\0\202\0\u3593\0\u35d4\0\202"+ + "\0\u3615\0\u3656\0\202\0\u3697\0\202\0\u36d8\0\u3719\0\u375a"+ + "\0\202\0\u379b\0\u37dc\0\u381d\0\u385e\0\u389f\0\202\0\u38e0"+ + "\0\202\0\202\0\u3921\0\u3962\0\u39a3\0\u39e4\0\u3a25\0\202"+ + "\0\202\0\u3a66\0\u3aa7\0\u3ae8\0\u3b29\0\202\0\u3b6a\0\u3bab"+ + "\0\u3bec\0\u3c2d\0\202\0\u3c6e\0\202\0\202\0\u3caf\0\u3cf0"+ + "\0\202\0\202\0\u3d31\0\u3d72\0\202\0\u3db3\0\u3df4\0\u3e35"+ + "\0\u3e76\0\202\0\202\0\u3eb7\0\202\0\u3ef8\0\u3f39\0\202"+ + "\0\u3f7a\0\202\0\202\0\u3fbb\0\202"; + + private static int [] zzUnpackRowMap() { + int [] result = new int[341]; + int offset = 0; + offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackRowMap(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int high = packed.charAt(i++) << 16; + result[j++] = high | packed.charAt(i++); + } + return j; + } + + /** + * The transition table of the DFA + */ + private static final int [] ZZ_TRANS = zzUnpackTrans(); + + private static final String ZZ_TRANS_PACKED_0 = + "\2\2\1\3\2\4\1\5\1\6\1\3\1\2\1\3"+ + "\1\7\1\10\2\3\1\10\1\11\1\3\1\12\1\13"+ + "\1\14\1\15\1\16\1\17\1\20\1\21\1\22\1\23"+ + "\1\24\1\10\1\25\1\26\3\3\1\27\1\30\3\3"+ + "\1\31\1\32\1\33\1\34\1\3\1\35\1\36\1\37"+ + "\1\40\1\41\1\42\1\43\1\44\1\45\1\46\1\47"+ + "\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57"+ + "\1\60\1\61\103\0\1\3\4\0\10\3\1\0\10\3"+ + "\2\0\3\3\1\0\16\3\30\0\2\4\101\0\1\62"+ + "\1\63\55\0\1\64\100\0\1\65\25\0\1\66\1\67"+ + "\1\70\1\71\1\0\1\67\1\72\6\0\1\66\5\0"+ + "\1\67\10\0\1\71\44\0\1\66\2\10\2\0\1\10"+ + "\1\72\6\0\1\66\5\0\1\10\63\0\1\73\63\0"+ + "\1\3\4\0\10\3\1\0\2\3\1\74\5\3\2\0"+ + "\3\3\1\0\2\3\1\75\13\3\27\0\1\3\4\0"+ + "\10\3\1\0\3\3\1\76\4\3\2\0\3\3\1\0"+ + "\16\3\27\0\1\3\4\0\10\3\1\0\6\3\1\77"+ + "\1\3\2\0\1\100\2\3\1\0\7\3\1\101\6\3"+ + "\27\0\1\3\4\0\10\3\1\0\5\3\1\102\1\103"+ + "\1\3\2\0\3\3\1\0\3\3\1\104\1\105\11\3"+ + "\27\0\1\3\4\0\10\3\1\0\7\3\1\106\2\0"+ + "\1\3\1\107\1\3\1\0\16\3\27\0\1\3\4\0"+ + "\10\3\1\0\10\3\2\0\3\3\1\0\3\3\1\110"+ + "\12\3\27\0\1\111\4\0\10\3\1\0\1\3\1\112"+ + "\6\3\2\0\3\3\1\0\2\3\1\113\5\3\1\114"+ + "\3\3\1\115\1\3\25\0\1\116\1\117\1\116\1\120"+ + "\24\116\1\121\50\116\1\22\1\122\1\22\1\123\25\22"+ + "\1\124\47\22\2\0\1\125\4\0\10\3\1\0\3\3"+ + "\1\126\1\3\1\127\2\3\2\0\3\3\1\0\16\3"+ + "\27\0\1\3\4\0\10\3\1\0\2\3\1\130\5\3"+ + "\2\0\3\3\1\0\3\3\1\131\4\3\1\132\5\3"+ + "\27\0\1\3\4\0\10\3\1\0\5\3\1\133\1\134"+ + "\1\3\2\0\3\3\1\0\2\3\1\135\1\136\12\3"+ + "\27\0\1\3\4\0\10\3\1\0\4\3\1\137\3\3"+ + "\2\0\1\140\2\3\1\0\6\3\1\141\7\3\27\0"+ + "\1\3\4\0\10\3\1\0\3\3\1\142\4\3\2\0"+ + "\3\3\1\0\3\3\1\143\12\3\27\0\1\3\4\0"+ + "\10\3\1\0\10\3\2\0\3\3\1\0\3\3\1\144"+ + "\12\3\27\0\1\145\4\0\10\3\1\0\2\3\1\146"+ + "\2\3\1\147\2\3\2\0\3\3\1\0\16\3\27\0"+ + "\1\3\4\0\10\3\1\0\10\3\2\0\3\3\1\0"+ + "\3\3\1\150\12\3\27\0\1\3\4\0\10\3\1\0"+ + "\10\3\2\0\3\3\1\0\2\3\1\151\13\3\111\0"+ + "\1\152\100\0\1\153\1\154\77\0\1\155\1\0\1\156"+ + "\76\0\1\157\100\0\1\160\6\0\1\161\71\0\1\162"+ + "\7\0\1\163\70\0\1\164\10\0\1\165\67\0\1\166"+ + "\11\0\1\167\66\0\1\170\100\0\1\171\14\0\3\62"+ + "\1\0\75\62\6\172\1\173\72\172\11\0\1\66\1\67"+ + "\1\70\2\0\1\67\1\72\6\0\1\66\5\0\1\67"+ + "\56\0\2\70\2\0\1\70\1\72\14\0\1\70\56\0"+ + "\2\174\1\0\2\174\1\0\1\174\2\0\3\174\5\0"+ + "\2\174\1\0\1\174\4\0\1\174\47\0\2\175\2\0"+ + "\1\175\15\0\1\175\63\0\1\176\63\0\1\177\4\0"+ + "\10\3\1\0\5\3\1\200\2\3\2\0\3\3\1\0"+ + "\10\3\1\201\5\3\27\0\1\3\4\0\10\3\1\0"+ + "\2\3\1\202\5\3\2\0\3\3\1\0\4\3\1\203"+ + "\11\3\27\0\1\3\4\0\10\3\1\0\1\3\1\204"+ + "\6\3\2\0\3\3\1\0\16\3\27\0\1\3\4\0"+ + "\10\3\1\0\7\3\1\205\2\0\3\3\1\0\16\3"+ + "\27\0\1\206\4\0\10\3\1\0\10\3\2\0\3\3"+ + "\1\0\16\3\27\0\1\3\4\0\10\3\1\0\1\3"+ + "\1\207\6\3\2\0\3\3\1\0\16\3\27\0\1\3"+ + "\4\0\10\3\1\0\6\3\1\210\1\3\2\0\3\3"+ + "\1\0\16\3\27\0\1\3\4\0\10\3\1\0\10\3"+ + "\2\0\3\3\1\0\3\3\1\211\12\3\27\0\1\3"+ + "\4\0\10\3\1\0\2\3\1\212\5\3\2\0\3\3"+ + "\1\0\16\3\27\0\1\3\4\0\10\3\1\0\10\3"+ + "\2\0\1\213\2\3\1\0\16\3\27\0\1\3\4\0"+ + "\10\3\1\0\7\3\1\214\2\0\3\3\1\0\16\3"+ + "\27\0\1\3\4\0\10\3\1\0\7\3\1\215\2\0"+ + "\3\3\1\0\16\3\27\0\1\3\4\0\10\3\1\0"+ + "\10\3\2\0\1\216\2\3\1\0\16\3\27\0\1\3"+ + "\4\0\10\3\1\0\10\3\2\0\3\3\1\0\12\3"+ + "\1\217\3\3\27\0\1\3\4\0\10\3\1\0\2\3"+ + "\1\220\2\3\1\221\2\3\2\0\3\3\1\0\16\3"+ + "\27\0\1\3\4\0\10\3\1\0\10\3\2\0\3\3"+ + "\1\0\3\3\1\222\12\3\27\0\1\3\4\0\10\3"+ + "\1\0\10\3\2\0\1\223\2\3\1\0\16\3\27\0"+ + "\1\3\4\0\10\3\1\0\10\3\2\0\3\3\1\0"+ + "\4\3\1\224\11\3\25\0\30\120\1\225\51\120\1\116"+ + "\1\226\7\120\1\227\3\120\1\230\2\120\2\116\1\120"+ + "\1\116\3\120\1\231\3\116\1\227\74\120\1\121\50\120"+ + "\1\123\1\22\1\232\7\123\1\22\3\123\1\22\2\123"+ + "\2\22\1\123\1\22\3\123\1\22\1\233\3\22\75\123"+ + "\1\234\47\123\2\0\1\3\4\0\10\3\1\0\6\3"+ + "\1\235\1\3\2\0\3\3\1\0\16\3\27\0\1\3"+ + "\4\0\10\3\1\0\10\3\2\0\3\3\1\0\14\3"+ + "\1\236\1\3\27\0\1\3\4\0\10\3\1\0\1\3"+ + "\1\237\6\3\2\0\3\3\1\0\16\3\27\0\1\3"+ + "\4\0\10\3\1\0\3\3\1\240\4\3\2\0\3\3"+ + "\1\0\16\3\27\0\1\3\4\0\10\3\1\0\10\3"+ + "\2\0\3\3\1\0\3\3\1\241\12\3\27\0\1\3"+ + "\4\0\10\3\1\0\1\3\1\242\6\3\2\0\3\3"+ + "\1\0\16\3\27\0\1\3\4\0\10\3\1\0\1\3"+ + "\1\243\5\3\1\244\2\0\3\3\1\0\16\3\27\0"+ + "\1\3\4\0\10\3\1\0\5\3\1\245\2\3\2\0"+ + "\3\3\1\0\16\3\27\0\1\3\4\0\10\3\1\0"+ + "\5\3\1\246\2\3\2\0\3\3\1\0\16\3\27\0"+ + "\1\3\4\0\10\3\1\0\10\3\2\0\1\247\2\3"+ + "\1\0\16\3\27\0\1\3\4\0\10\3\1\0\1\3"+ + "\1\250\5\3\1\251\2\0\3\3\1\0\16\3\27\0"+ + "\1\3\4\0\10\3\1\0\10\3\2\0\3\3\1\0"+ + "\12\3\1\252\3\3\27\0\1\3\4\0\10\3\1\0"+ + "\4\3\1\253\3\3\2\0\3\3\1\0\16\3\27\0"+ + "\1\254\4\0\10\3\1\0\10\3\2\0\3\3\1\0"+ + "\16\3\27\0\1\3\4\0\10\3\1\0\1\3\1\255"+ + "\6\3\2\0\3\3\1\0\16\3\27\0\1\3\4\0"+ + "\10\3\1\0\10\3\2\0\1\3\1\256\1\3\1\0"+ + "\16\3\27\0\1\3\4\0\10\3\1\0\10\3\2\0"+ + "\3\3\1\0\3\3\1\257\1\260\11\3\27\0\1\3"+ + "\4\0\10\3\1\0\10\3\2\0\3\3\1\0\1\261"+ + "\15\3\27\0\1\3\4\0\10\3\1\0\6\3\1\262"+ + "\1\3\2\0\3\3\1\0\4\3\1\263\11\3\27\0"+ + "\1\3\4\0\10\3\1\0\10\3\2\0\3\3\1\0"+ + "\4\3\1\264\11\3\111\0\1\265\1\266\77\0\1\267"+ + "\14\0\6\172\1\270\72\172\5\271\1\272\1\173\72\271"+ + "\11\0\1\66\2\174\1\0\2\174\1\0\1\174\2\0"+ + "\3\174\1\66\4\0\2\174\1\0\1\174\4\0\1\174"+ + "\47\0\2\175\2\0\1\175\1\0\1\273\3\0\1\273"+ + "\7\0\1\175\46\0\1\3\4\0\10\3\1\0\3\3"+ + "\1\274\4\3\2\0\3\3\1\0\16\3\27\0\1\3"+ + "\4\0\10\3\1\0\10\3\2\0\1\275\2\3\1\0"+ + "\16\3\27\0\1\3\4\0\10\3\1\0\10\3\2\0"+ + "\3\3\1\0\3\3\1\276\12\3\27\0\1\3\4\0"+ + "\10\3\1\0\7\3\1\277\2\0\3\3\1\0\16\3"+ + "\27\0\1\300\4\0\10\3\1\0\10\3\2\0\3\3"+ + "\1\0\16\3\27\0\1\3\4\0\10\3\1\0\3\3"+ + "\1\301\4\3\2\0\3\3\1\0\16\3\27\0\1\3"+ + "\4\0\10\3\1\0\10\3\2\0\3\3\1\0\6\3"+ + "\1\302\7\3\27\0\1\3\4\0\10\3\1\0\3\3"+ + "\1\303\4\3\2\0\3\3\1\0\16\3\27\0\1\3"+ + "\4\0\10\3\1\0\7\3\1\177\2\0\3\3\1\0"+ + "\16\3\27\0\1\3\4\0\10\3\1\0\5\3\1\304"+ + "\2\3\2\0\3\3\1\0\16\3\27\0\1\3\4\0"+ + "\10\3\1\0\5\3\1\305\2\3\2\0\3\3\1\0"+ + "\16\3\27\0\1\3\4\0\10\3\1\0\3\3\1\306"+ + "\4\3\2\0\3\3\1\0\16\3\27\0\1\3\4\0"+ + "\10\3\1\0\1\3\1\307\6\3\2\0\3\3\1\0"+ + "\16\3\27\0\1\3\4\0\10\3\1\0\10\3\2\0"+ + "\3\3\1\0\11\3\1\310\4\3\27\0\1\3\4\0"+ + "\10\3\1\0\3\3\1\311\4\3\2\0\3\3\1\0"+ + "\16\3\27\0\1\3\4\0\10\3\1\0\10\3\2\0"+ + "\3\3\1\0\4\3\1\312\11\3\27\0\1\3\4\0"+ + "\10\3\1\0\1\3\1\313\6\3\2\0\3\3\1\0"+ + "\16\3\27\0\1\3\4\0\10\3\1\0\2\3\1\314"+ + "\5\3\2\0\3\3\1\0\16\3\27\0\1\3\4\0"+ + "\10\3\1\0\10\3\2\0\3\3\1\0\1\315\15\3"+ + "\27\0\1\3\4\0\10\3\1\0\1\3\1\316\6\3"+ + "\2\0\3\3\1\0\16\3\25\0\2\120\1\226\7\120"+ + "\2\317\1\120\2\317\1\120\1\317\2\120\3\317\2\120"+ + "\1\121\2\120\2\317\1\120\1\317\4\120\1\317\47\120"+ + "\1\230\3\120\1\230\11\120\1\225\3\120\1\230\56\120"+ + "\1\116\3\120\1\116\11\120\1\225\3\120\1\116\44\120"+ + "\30\0\1\225\50\0\2\123\1\232\7\123\2\320\1\123"+ + "\2\320\1\123\1\320\2\123\3\320\3\123\1\234\1\123"+ + "\2\320\1\123\1\320\4\123\1\320\35\123\1\321\1\322"+ + "\1\321\1\0\25\321\1\124\47\321\2\0\1\3\4\0"+ + "\10\3\1\0\6\3\1\323\1\3\2\0\3\3\1\0"+ + "\16\3\27\0\1\3\4\0\10\3\1\0\10\3\2\0"+ + "\3\3\1\0\4\3\1\324\11\3\27\0\1\3\4\0"+ + "\10\3\1\0\5\3\1\325\2\3\2\0\3\3\1\0"+ + "\16\3\27\0\1\3\4\0\10\3\1\0\6\3\1\326"+ + "\1\3\2\0\3\3\1\0\16\3\27\0\1\3\4\0"+ + "\10\3\1\0\3\3\1\327\4\3\2\0\3\3\1\0"+ + "\16\3\27\0\1\3\4\0\10\3\1\0\10\3\2\0"+ + "\3\3\1\0\1\330\15\3\27\0\1\3\4\0\10\3"+ + "\1\0\3\3\1\331\4\3\2\0\3\3\1\0\16\3"+ + "\27\0\1\3\4\0\10\3\1\0\7\3\1\332\2\0"+ + "\3\3\1\0\16\3\27\0\1\3\4\0\10\3\1\0"+ + "\2\3\1\333\5\3\2\0\3\3\1\0\16\3\27\0"+ + "\1\3\4\0\10\3\1\0\1\3\1\334\5\3\1\335"+ + "\2\0\3\3\1\0\16\3\27\0\1\3\4\0\10\3"+ + "\1\0\3\3\1\336\4\3\2\0\3\3\1\0\16\3"+ + "\27\0\1\3\4\0\10\3\1\0\1\3\1\337\6\3"+ + "\2\0\3\3\1\0\16\3\27\0\1\3\4\0\10\3"+ + "\1\0\6\3\1\340\1\3\2\0\3\3\1\0\3\3"+ + "\1\341\12\3\27\0\1\3\4\0\10\3\1\0\5\3"+ + "\1\342\2\3\2\0\3\3\1\0\16\3\27\0\1\3"+ + "\4\0\10\3\1\0\10\3\2\0\1\3\1\343\1\3"+ + "\1\0\16\3\27\0\1\3\4\0\10\3\1\0\10\3"+ + "\2\0\3\3\1\0\3\3\1\344\12\3\27\0\1\3"+ + "\4\0\10\3\1\0\6\3\1\345\1\3\2\0\3\3"+ + "\1\0\16\3\27\0\1\3\4\0\10\3\1\0\1\3"+ + "\1\346\6\3\2\0\3\3\1\0\16\3\27\0\1\3"+ + "\4\0\10\3\1\0\10\3\2\0\3\3\1\0\13\3"+ + "\1\347\2\3\27\0\1\3\4\0\10\3\1\0\10\3"+ + "\2\0\3\3\1\0\1\3\1\350\14\3\27\0\1\3"+ + "\4\0\10\3\1\0\5\3\1\351\2\3\2\0\3\3"+ + "\1\0\16\3\27\0\1\3\4\0\10\3\1\0\10\3"+ + "\2\0\3\3\1\0\5\3\1\352\10\3\27\0\1\3"+ + "\4\0\10\3\1\0\6\3\1\353\1\3\2\0\3\3"+ + "\1\0\16\3\111\0\1\354\14\0\5\172\1\272\1\270"+ + "\72\172\6\271\1\355\72\271\2\0\1\3\4\0\10\3"+ + "\1\0\7\3\1\356\2\0\3\3\1\0\16\3\27\0"+ + "\1\3\4\0\10\3\1\0\10\3\2\0\3\3\1\0"+ + "\14\3\1\357\1\3\27\0\1\3\4\0\10\3\1\0"+ + "\2\3\1\360\5\3\2\0\3\3\1\0\16\3\27\0"+ + "\1\3\4\0\10\3\1\0\10\3\2\0\1\361\2\3"+ + "\1\0\16\3\27\0\1\3\4\0\10\3\1\0\1\3"+ + "\1\362\6\3\2\0\3\3\1\0\16\3\27\0\1\3"+ + "\4\0\10\3\1\0\6\3\1\363\1\3\2\0\3\3"+ + "\1\0\16\3\27\0\1\3\4\0\10\3\1\0\2\3"+ + "\1\364\5\3\2\0\3\3\1\0\16\3\27\0\1\3"+ + "\4\0\10\3\1\0\2\3\1\365\5\3\2\0\3\3"+ + "\1\0\16\3\27\0\1\3\4\0\10\3\1\0\2\3"+ + "\1\366\5\3\2\0\3\3\1\0\16\3\27\0\1\3"+ + "\4\0\10\3\1\0\10\3\2\0\3\3\1\0\1\367"+ + "\15\3\27\0\1\3\4\0\10\3\1\0\10\3\2\0"+ + "\3\3\1\0\4\3\1\370\11\3\27\0\1\3\4\0"+ + "\10\3\1\0\1\3\1\371\6\3\2\0\3\3\1\0"+ + "\16\3\27\0\1\3\4\0\10\3\1\0\10\3\2\0"+ + "\3\3\1\0\2\3\1\372\13\3\27\0\1\3\4\0"+ + "\10\3\1\0\10\3\2\0\3\3\1\0\1\373\15\3"+ + "\25\0\12\120\2\374\1\120\2\374\1\120\1\374\2\120"+ + "\3\374\2\120\1\121\2\120\2\374\1\120\1\374\4\120"+ + "\1\374\35\120\12\123\2\375\1\123\2\375\1\123\1\375"+ + "\2\123\3\375\3\123\1\234\1\123\2\375\1\123\1\375"+ + "\4\123\1\375\35\123\1\0\1\321\1\376\7\0\1\321"+ + "\3\0\1\321\2\0\2\321\1\0\1\321\3\0\5\321"+ + "\46\0\1\3\4\0\10\3\1\0\10\3\2\0\3\3"+ + "\1\0\13\3\1\377\2\3\27\0\1\3\4\0\10\3"+ + "\1\0\10\3\2\0\3\3\1\0\1\3\1\u0100\14\3"+ + "\27\0\1\3\4\0\10\3\1\0\3\3\1\u0101\4\3"+ + "\2\0\3\3\1\0\16\3\27\0\1\3\4\0\10\3"+ + "\1\0\10\3\2\0\3\3\1\0\2\3\1\u0102\13\3"+ + "\27\0\1\3\4\0\10\3\1\0\7\3\1\u0103\2\0"+ + "\3\3\1\0\16\3\27\0\1\3\4\0\10\3\1\0"+ + "\10\3\2\0\3\3\1\0\4\3\1\u0104\11\3\27\0"+ + "\1\3\4\0\10\3\1\0\1\3\1\u0105\6\3\2\0"+ + "\3\3\1\0\16\3\27\0\1\3\4\0\10\3\1\0"+ + "\2\3\1\u0106\5\3\2\0\3\3\1\0\16\3\27\0"+ + "\1\3\4\0\10\3\1\0\5\3\1\u0107\2\3\2\0"+ + "\3\3\1\0\16\3\27\0\1\3\4\0\10\3\1\0"+ + "\3\3\1\u0108\4\3\2\0\3\3\1\0\16\3\27\0"+ + "\1\3\4\0\10\3\1\0\2\3\1\u0109\5\3\2\0"+ + "\3\3\1\0\16\3\27\0\1\u010a\4\0\10\3\1\0"+ + "\10\3\2\0\3\3\1\0\16\3\27\0\1\3\4\0"+ + "\10\3\1\0\6\3\1\u010b\1\3\2\0\3\3\1\0"+ + "\16\3\27\0\1\3\4\0\10\3\1\0\10\3\2\0"+ + "\3\3\1\0\4\3\1\u010c\11\3\27\0\1\3\4\0"+ + "\10\3\1\0\3\3\1\u010d\4\3\2\0\3\3\1\0"+ + "\16\3\27\0\1\3\4\0\10\3\1\0\5\3\1\u010e"+ + "\2\3\2\0\3\3\1\0\16\3\27\0\1\3\4\0"+ + "\10\3\1\0\5\3\1\u010f\2\3\2\0\3\3\1\0"+ + "\16\3\27\0\1\3\4\0\10\3\1\0\1\3\1\u0110"+ + "\6\3\2\0\3\3\1\0\16\3\27\0\1\3\4\0"+ + "\10\3\1\0\3\3\1\u0111\4\3\2\0\3\3\1\0"+ + "\16\3\25\0\5\271\1\u0112\1\355\72\271\2\0\1\3"+ + "\4\0\10\3\1\0\10\3\2\0\3\3\1\0\4\3"+ + "\1\u0113\11\3\27\0\1\3\4\0\10\3\1\0\7\3"+ + "\1\u0114\2\0\3\3\1\0\16\3\27\0\1\3\4\0"+ + "\10\3\1\0\10\3\2\0\1\u0115\2\3\1\0\16\3"+ + "\27\0\1\3\4\0\10\3\1\0\10\3\2\0\3\3"+ + "\1\0\5\3\1\u0116\10\3\27\0\1\3\4\0\10\3"+ + "\1\0\6\3\1\u0117\1\3\2\0\3\3\1\0\16\3"+ + "\27\0\1\3\4\0\10\3\1\0\1\3\1\u0118\6\3"+ + "\2\0\3\3\1\0\16\3\27\0\1\3\4\0\10\3"+ + "\1\0\5\3\1\u0119\2\3\2\0\3\3\1\0\16\3"+ + "\27\0\1\3\4\0\10\3\1\0\1\3\1\u011a\6\3"+ + "\2\0\3\3\1\0\16\3\27\0\1\3\4\0\10\3"+ + "\1\0\10\3\2\0\3\3\1\0\1\u011b\15\3\27\0"+ + "\1\3\4\0\10\3\1\0\2\3\1\u011c\5\3\2\0"+ + "\3\3\1\0\16\3\27\0\1\3\4\0\10\3\1\0"+ + "\10\3\2\0\3\3\1\0\2\3\1\u011d\13\3\25\0"+ + "\12\120\2\u011e\1\120\2\u011e\1\120\1\u011e\2\120\3\u011e"+ + "\2\120\1\121\2\120\2\u011e\1\120\1\u011e\4\120\1\u011e"+ + "\35\120\12\123\2\u011f\1\123\2\u011f\1\123\1\u011f\2\123"+ + "\3\u011f\3\123\1\234\1\123\2\u011f\1\123\1\u011f\4\123"+ + "\1\u011f\35\123\2\0\1\376\7\0\2\u0120\1\0\2\u0120"+ + "\1\0\1\u0120\2\0\3\u0120\5\0\2\u0120\1\0\1\u0120"+ + "\4\0\1\u0120\37\0\1\3\4\0\10\3\1\0\3\3"+ + "\1\u0121\4\3\2\0\3\3\1\0\16\3\27\0\1\3"+ + "\4\0\10\3\1\0\5\3\1\u0122\2\3\2\0\3\3"+ + "\1\0\16\3\27\0\1\3\4\0\10\3\1\0\10\3"+ + "\2\0\1\u0123\2\3\1\0\16\3\27\0\1\3\4\0"+ + "\10\3\1\0\4\3\1\u0124\3\3\2\0\3\3\1\0"+ + "\16\3\27\0\1\3\4\0\10\3\1\0\10\3\2\0"+ + "\1\u0125\2\3\1\0\16\3\27\0\1\3\4\0\10\3"+ + "\1\0\10\3\2\0\3\3\1\0\6\3\1\u0126\7\3"+ + "\27\0\1\3\4\0\10\3\1\0\1\3\1\u0127\6\3"+ + "\2\0\3\3\1\0\16\3\27\0\1\3\4\0\10\3"+ + "\1\0\6\3\1\u0128\1\3\2\0\3\3\1\0\16\3"+ + "\27\0\1\3\4\0\10\3\1\0\3\3\1\u0129\4\3"+ + "\2\0\3\3\1\0\16\3\27\0\1\3\4\0\10\3"+ + "\1\0\10\3\2\0\3\3\1\0\1\u012a\15\3\27\0"+ + "\1\3\4\0\10\3\1\0\10\3\2\0\3\3\1\0"+ + "\1\u012b\15\3\27\0\1\3\4\0\10\3\1\0\1\3"+ + "\1\u012c\6\3\2\0\3\3\1\0\16\3\27\0\1\3"+ + "\4\0\10\3\1\0\10\3\2\0\3\3\1\0\11\3"+ + "\1\u012d\4\3\27\0\1\3\4\0\10\3\1\0\10\3"+ + "\2\0\3\3\1\0\4\3\1\u012e\11\3\27\0\1\3"+ + "\4\0\10\3\1\0\3\3\1\u012f\4\3\2\0\3\3"+ + "\1\0\16\3\27\0\1\3\4\0\10\3\1\0\7\3"+ + "\1\u0130\2\0\3\3\1\0\16\3\27\0\1\3\4\0"+ + "\10\3\1\0\10\3\2\0\3\3\1\0\10\3\1\u0131"+ + "\5\3\27\0\1\3\4\0\10\3\1\0\10\3\2\0"+ + "\3\3\1\0\1\u0132\15\3\27\0\1\3\4\0\10\3"+ + "\1\0\4\3\1\u0133\3\3\2\0\3\3\1\0\16\3"+ + "\27\0\1\3\4\0\10\3\1\0\10\3\2\0\3\3"+ + "\1\0\3\3\1\u0134\12\3\25\0\12\120\2\116\1\120"+ + "\2\116\1\120\1\116\2\120\3\116\2\120\1\121\2\120"+ + "\2\116\1\120\1\116\4\120\1\116\35\120\12\123\2\22"+ + "\1\123\2\22\1\123\1\22\2\123\3\22\3\123\1\234"+ + "\1\123\2\22\1\123\1\22\4\123\1\22\35\123\12\0"+ + "\2\u0135\1\0\2\u0135\1\0\1\u0135\2\0\3\u0135\5\0"+ + "\2\u0135\1\0\1\u0135\4\0\1\u0135\37\0\1\3\4\0"+ + "\10\3\1\0\10\3\2\0\1\u0136\2\3\1\0\16\3"+ + "\27\0\1\u0137\4\0\10\3\1\0\10\3\2\0\3\3"+ + "\1\0\16\3\27\0\1\3\4\0\10\3\1\0\5\3"+ + "\1\u0138\2\3\2\0\3\3\1\0\16\3\27\0\1\3"+ + "\4\0\10\3\1\0\10\3\2\0\3\3\1\0\1\u0139"+ + "\15\3\27\0\1\3\4\0\10\3\1\0\3\3\1\u013a"+ + "\4\3\2\0\3\3\1\0\16\3\27\0\1\3\4\0"+ + "\10\3\1\0\1\3\1\u013b\6\3\2\0\3\3\1\0"+ + "\16\3\27\0\1\3\4\0\10\3\1\0\1\3\1\u013c"+ + "\6\3\2\0\3\3\1\0\16\3\27\0\1\3\4\0"+ + "\10\3\1\0\3\3\1\u013d\4\3\2\0\3\3\1\0"+ + "\16\3\27\0\1\3\4\0\10\3\1\0\3\3\1\u013e"+ + "\4\3\2\0\3\3\1\0\16\3\27\0\1\3\4\0"+ + "\10\3\1\0\6\3\1\u013f\1\3\2\0\3\3\1\0"+ + "\16\3\27\0\1\3\4\0\10\3\1\0\10\3\2\0"+ + "\1\u0140\2\3\1\0\16\3\27\0\1\3\4\0\10\3"+ + "\1\0\1\3\1\u0141\6\3\2\0\3\3\1\0\16\3"+ + "\27\0\1\3\4\0\10\3\1\0\10\3\2\0\3\3"+ + "\1\0\12\3\1\u0142\3\3\27\0\1\3\4\0\10\3"+ + "\1\0\10\3\2\0\1\u0143\2\3\1\0\16\3\37\0"+ + "\2\u0144\1\0\2\u0144\1\0\1\u0144\2\0\3\u0144\5\0"+ + "\2\u0144\1\0\1\u0144\4\0\1\u0144\37\0\1\3\4\0"+ + "\10\3\1\0\3\3\1\u0145\4\3\2\0\3\3\1\0"+ + "\16\3\27\0\1\3\4\0\10\3\1\0\10\3\2\0"+ + "\3\3\1\0\1\u0146\15\3\27\0\1\3\4\0\10\3"+ + "\1\0\3\3\1\u0147\4\3\2\0\3\3\1\0\16\3"+ + "\27\0\1\3\4\0\10\3\1\0\10\3\2\0\1\u0148"+ + "\2\3\1\0\16\3\27\0\1\3\4\0\10\3\1\0"+ + "\3\3\1\u0149\4\3\2\0\3\3\1\0\16\3\27\0"+ + "\1\3\4\0\10\3\1\0\3\3\1\u014a\4\3\2\0"+ + "\3\3\1\0\16\3\27\0\1\3\4\0\10\3\1\0"+ + "\1\3\1\u014b\6\3\2\0\3\3\1\0\16\3\27\0"+ + "\1\3\4\0\10\3\1\0\10\3\2\0\3\3\1\0"+ + "\4\3\1\u014c\11\3\37\0\2\321\1\0\2\321\1\0"+ + "\1\321\2\0\3\321\5\0\2\321\1\0\1\321\4\0"+ + "\1\321\37\0\1\3\4\0\10\3\1\0\3\3\1\u014d"+ + "\4\3\2\0\3\3\1\0\16\3\27\0\1\3\4\0"+ + "\10\3\1\0\10\3\2\0\3\3\1\0\3\3\1\u014e"+ + "\12\3\27\0\1\3\4\0\10\3\1\0\1\3\1\u014f"+ + "\6\3\2\0\3\3\1\0\16\3\27\0\1\3\4\0"+ + "\10\3\1\0\10\3\2\0\3\3\1\0\5\3\1\u0150"+ + "\10\3\27\0\1\3\4\0\10\3\1\0\10\3\2\0"+ + "\3\3\1\0\15\3\1\u0151\27\0\1\3\4\0\10\3"+ + "\1\0\4\3\1\u0152\3\3\2\0\3\3\1\0\16\3"+ + "\27\0\1\3\4\0\10\3\1\0\7\3\1\u0153\2\0"+ + "\3\3\1\0\16\3\27\0\1\3\4\0\10\3\1\0"+ + "\3\3\1\u0154\4\3\2\0\3\3\1\0\16\3\27\0"+ + "\1\3\4\0\10\3\1\0\10\3\2\0\3\3\1\0"+ + "\5\3\1\u0155\10\3\25\0"; + + private static int [] zzUnpackTrans() { + int [] result = new int[16380]; + int offset = 0; + offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackTrans(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + value--; + do result[j++] = value; while (--count > 0); + } + return j; + } + + + /* error codes */ + private static final int ZZ_UNKNOWN_ERROR = 0; + private static final int ZZ_NO_MATCH = 1; + private static final int ZZ_PUSHBACK_2BIG = 2; + + /* error messages for the codes above */ + private static final String ZZ_ERROR_MSG[] = { + "Unkown internal scanner error", + "Error: could not match input", + "Error: pushback value was too large" + }; + + /** + * ZZ_ATTRIBUTE[aState] contains the attributes of state aState + */ + private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute(); + + private static final String ZZ_ATTRIBUTE_PACKED_0 = + "\1\0\1\11\22\1\1\11\7\1\10\11\4\1\3\11"+ + "\7\1\1\0\3\11\1\1\4\0\25\1\1\11\2\1"+ + "\1\11\25\1\2\11\1\1\1\11\1\1\13\11\2\0"+ + "\1\1\1\0\1\11\26\1\1\11\6\1\1\11\30\1"+ + "\1\11\1\1\1\11\2\0\2\11\25\1\2\0\31\1"+ + "\1\11\1\0\20\1\1\0\23\1\1\11\15\1\1\0"+ + "\24\1\1\0\16\1\1\0\21\1"; + + private static int [] zzUnpackAttribute() { + int [] result = new int[341]; + int offset = 0; + offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackAttribute(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); + } + return j; + } + + /** the input device */ + private java.io.Reader zzReader; + + /** the current state of the DFA */ + private int zzState; + + /** the current lexical state */ + private int zzLexicalState = YYINITIAL; + + /** this buffer contains the current text to be matched and is + the source of the yytext() string */ + private char zzBuffer[] = new char[ZZ_BUFFERSIZE]; + + /** the textposition at the last accepting state */ + private int zzMarkedPos; + + /** the current text position in the buffer */ + private int zzCurrentPos; + + /** startRead marks the beginning of the yytext() string in the buffer */ + private int zzStartRead; + + /** endRead marks the last character in the buffer, that has been read + from input */ + private int zzEndRead; + + /** number of newlines encountered up to the start of the matched text */ + private int yyline; + + /** the number of characters up to the start of the matched text */ + private int yychar; + + /** + * the number of characters from the last newline up to the start of the + * matched text + */ + private int yycolumn; + + /** zzAtEOF == true <=> the scanner is at the EOF */ + private boolean zzAtEOF; + + /* user code: */ + + /** + * Whether comments should be returned as tokens. + */ + private boolean returnComments; + + /** + * Whether whitespace should be returned as tokens. + */ + private boolean returnWhitespace; + + /** + * Whether the last documentation comment parsed should be kept. + */ + private boolean keepLastDocComment; + + /** + * The last documentation comment parsed, if that feature is enabled. + */ + private String lastDocComment; + + + private Token createToken(int type) { + return createToken(type, false); + } + + + private Token createToken(int type, boolean invalid) { + return new TokenImpl(type, yytext(), yyline, yycolumn, yychar, invalid); + } + + + /** + * Returns the current column into the current line. + * + * @return The current column. + */ + public int getColumn() { + return yycolumn; + } + + + /** + * Returns the last documentation comment parsed, if this feature is + * enabled. The "last documentation comment" is cleared when this method + * returns. + * + * @return The last documentation comment parsed, or null + * if the feature is disabled. + * @see #setKeepLastDocComment(boolean) + */ + public String getLastDocComment() { + String comment = lastDocComment; + lastDocComment = null; + return comment; + } + + + /** + * Returns the current line into the document. + * + * @return The current line. + */ + public int getLine() { + return yyline; + } + + + /** + * Returns the current offset into the document. + * + * @return The offset. + */ + public int getOffset() { + return yychar; + } + + + /** + * Returns whether comments are returned as tokens. + * + * @return Whether comments are returned as tokens. + * @see #getReturnWhitespace() + */ + public boolean getReturnComments() { + return returnComments; + } + + + /** + * Returns whether whitespace is returned as tokens. + * + * @return Whether whitespace is returned as tokens. + * @see #getReturnComments() + */ + public boolean getReturnWhitespace() { + return returnWhitespace; + } + + + /** + * Sets whether the last documentation comment should be kept. + * + * @param keep Whether to keep the last documentation comment. + * @see #getLastDocComment() + */ + public void setKeepLastDocComment(boolean keep) { + keepLastDocComment = keep; + } + + + /** + * Sets whether comments are returned as tokens. + * + * @param returnComments Whether comments should be returned as tokens. + * @see #getReturnComments() + * @see #setReturnWhitespace(boolean) + */ + public void setReturnComments(boolean returnComments) { + this.returnComments = returnComments; + } + + + /** + * Sets whether whitespace is returned as tokens. + * + * @param returnWhitespace Whether whitespace should be returned as tokens. + * @see #getReturnWhitespace() + * @see #setReturnComments(boolean) + */ + public void setReturnWhitespace(boolean returnWhitespace) { + this.returnWhitespace = returnWhitespace; + } + + + + + /** + * Creates a new scanner + * There is also a java.io.InputStream version of this constructor. + * + * @param in the java.io.Reader to read input from. + */ + SourceCodeScanner(java.io.Reader in) { + this.zzReader = in; + } + + /** + * Creates a new scanner. + * There is also java.io.Reader version of this constructor. + * + * @param in the java.io.Inputstream to read input from. + */ + SourceCodeScanner(java.io.InputStream in) { + this(new java.io.InputStreamReader(in)); + } + + /** + * Unpacks the compressed character translation table. + * + * @param packed the packed character translation table + * @return the unpacked character translation table + */ + private static char [] zzUnpackCMap(String packed) { + char [] map = new char[0x10000]; + int i = 0; /* index in packed string */ + int j = 0; /* index in unpacked array */ + while (i < 1776) { + int count = packed.charAt(i++); + char value = packed.charAt(i++); + do map[j++] = value; while (--count > 0); + } + return map; + } + + + /** + * Refills the input buffer. + * + * @return false, iff there was new input. + * + * @exception java.io.IOException if any I/O-Error occurs + */ + private boolean zzRefill() throws java.io.IOException { + + /* first: make room (if you can) */ + if (zzStartRead > 0) { + System.arraycopy(zzBuffer, zzStartRead, + zzBuffer, 0, + zzEndRead-zzStartRead); + + /* translate stored positions */ + zzEndRead-= zzStartRead; + zzCurrentPos-= zzStartRead; + zzMarkedPos-= zzStartRead; + zzStartRead = 0; + } + + /* is the buffer big enough? */ + if (zzCurrentPos >= zzBuffer.length) { + /* if not: blow it up */ + char newBuffer[] = new char[zzCurrentPos*2]; + System.arraycopy(zzBuffer, 0, newBuffer, 0, zzBuffer.length); + zzBuffer = newBuffer; + } + + /* finally: fill the buffer with new input */ + int numRead = zzReader.read(zzBuffer, zzEndRead, + zzBuffer.length-zzEndRead); + + if (numRead < 0) { + return true; + } + else { + zzEndRead+= numRead; + return false; + } + } + + + /** + * Closes the input stream. + */ + public final void yyclose() throws java.io.IOException { + zzAtEOF = true; /* indicate end of file */ + zzEndRead = zzStartRead; /* invalidate buffer */ + + if (zzReader != null) + zzReader.close(); + } + + + /** + * Resets the scanner to read from a new input stream. + * Does not close the old reader. + * + * All internal variables are reset, the old input stream + * cannot be reused (internal buffer is discarded and lost). + * Lexical state is set to ZZ_INITIAL. + * + * @param reader the new input stream + */ + public final void yyreset(java.io.Reader reader) { + zzReader = reader; + zzAtEOF = false; + zzEndRead = zzStartRead = 0; + zzCurrentPos = zzMarkedPos = 0; + yyline = yychar = yycolumn = 0; + zzLexicalState = YYINITIAL; + } + + + /** + * Returns the current lexical state. + */ + public final int yystate() { + return zzLexicalState; + } + + + /** + * Enters a new lexical state + * + * @param newState the new lexical state + */ + public final void yybegin(int newState) { + zzLexicalState = newState; + } + + + /** + * Returns the text matched by the current regular expression. + */ + public final String yytext() { + return new String( zzBuffer, zzStartRead, zzMarkedPos-zzStartRead ); + } + + + /** + * Returns the character at position pos from the + * matched text. + * + * It is equivalent to yytext().charAt(pos), but faster + * + * @param pos the position of the character to fetch. + * A value from 0 to yylength()-1. + * + * @return the character at position pos + */ + public final char yycharat(int pos) { + return zzBuffer[zzStartRead+pos]; + } + + + /** + * Returns the length of the matched text region. + */ + public final int yylength() { + return zzMarkedPos-zzStartRead; + } + + + /** + * Reports an error that occured while scanning. + * + * In a wellformed scanner (no or only correct usage of + * yypushback(int) and a match-all fallback rule) this method + * will only be called with things that "Can't Possibly Happen". + * If this method is called, something is seriously wrong + * (e.g. a JFlex bug producing a faulty scanner etc.). + * + * Usual syntax/scanner level error handling should be done + * in error fallback rules. + * + * @param errorCode the code of the errormessage to display + */ + private void zzScanError(int errorCode) { + String message; + try { + message = ZZ_ERROR_MSG[errorCode]; + } + catch (ArrayIndexOutOfBoundsException e) { + message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR]; + } + + throw new Error(message); + } + + + /** + * Pushes the specified amount of characters back into the input stream. + * + * They will be read again by then next call of the scanning method + * + * @param number the number of characters to be read again. + * This number must not be greater than yylength()! + */ + public void yypushback(int number) { + if ( number > yylength() ) + zzScanError(ZZ_PUSHBACK_2BIG); + + zzMarkedPos -= number; + } + + + /** + * Resumes scanning until the next regular expression is matched, + * the end of input is encountered or an I/O-Error occurs. + * + * @return the next token + * @exception java.io.IOException if any I/O-Error occurs + */ + public org.fife.rsta.ac.bsh.rjc.lexer.Token yylex() throws java.io.IOException { + int zzInput; + int zzAction; + + // cached fields: + int zzCurrentPosL; + int zzMarkedPosL; + int zzEndReadL = zzEndRead; + char [] zzBufferL = zzBuffer; + char [] zzCMapL = ZZ_CMAP; + + int [] zzTransL = ZZ_TRANS; + int [] zzRowMapL = ZZ_ROWMAP; + int [] zzAttrL = ZZ_ATTRIBUTE; + + while (true) { + zzMarkedPosL = zzMarkedPos; + + yychar+= zzMarkedPosL-zzStartRead; + + boolean zzR = false; + for (zzCurrentPosL = zzStartRead; zzCurrentPosL < zzMarkedPosL; + zzCurrentPosL++) { + switch (zzBufferL[zzCurrentPosL]) { + case '\u000B': + case '\u000C': + case '\u0085': + case '\u2028': + case '\u2029': + yyline++; + yycolumn = 0; + zzR = false; + break; + case '\r': + yyline++; + yycolumn = 0; + zzR = true; + break; + case '\n': + if (zzR) + zzR = false; + else { + yyline++; + yycolumn = 0; + } + break; + default: + zzR = false; + yycolumn++; + } + } + + if (zzR) { + // peek one character ahead if it is \n (if we have counted one line too much) + boolean zzPeek; + if (zzMarkedPosL < zzEndReadL) + zzPeek = zzBufferL[zzMarkedPosL] == '\n'; + else if (zzAtEOF) + zzPeek = false; + else { + boolean eof = zzRefill(); + zzEndReadL = zzEndRead; + zzMarkedPosL = zzMarkedPos; + zzBufferL = zzBuffer; + if (eof) + zzPeek = false; + else + zzPeek = zzBufferL[zzMarkedPosL] == '\n'; + } + if (zzPeek) yyline--; + } + zzAction = -1; + + zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL; + + zzState = zzLexicalState; + + + zzForAction: { + while (true) { + + if (zzCurrentPosL < zzEndReadL) + zzInput = zzBufferL[zzCurrentPosL++]; + else if (zzAtEOF) { + zzInput = YYEOF; + break zzForAction; + } + else { + // store back cached positions + zzCurrentPos = zzCurrentPosL; + zzMarkedPos = zzMarkedPosL; + boolean eof = zzRefill(); + // get translated positions and possibly new buffer + zzCurrentPosL = zzCurrentPos; + zzMarkedPosL = zzMarkedPos; + zzBufferL = zzBuffer; + zzEndReadL = zzEndRead; + if (eof) { + zzInput = YYEOF; + break zzForAction; + } + else { + zzInput = zzBufferL[zzCurrentPosL++]; + } + } + int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMapL[zzInput] ]; + if (zzNext == -1) break zzForAction; + zzState = zzNext; + + int zzAttributes = zzAttrL[zzState]; + if ( (zzAttributes & 1) == 1 ) { + zzAction = zzState; + zzMarkedPosL = zzCurrentPosL; + if ( (zzAttributes & 8) == 8 ) break zzForAction; + } + + } + } + + // store back cached position + zzMarkedPos = zzMarkedPosL; + + switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) { + case 87: + { return createToken(KEYWORD_THROWS); + } + case 112: break; + case 11: + { return createToken(SEPARATOR_LPAREN); + } + case 113: break; + case 105: + { return createToken(KEYWORD_VOLATILE); + } + case 114: break; + case 95: + { return createToken(KEYWORD_PUBLIC); + } + case 115: break; + case 5: + { return createToken(OPERATOR_TIMES); + } + case 116: break; + case 71: + { return createToken(KEYWORD_CASE); + } + case 117: break; + case 34: + { return createToken(OPERATOR_TIMES_EQUALS); + } + case 118: break; + case 89: + { return createToken(KEYWORD_ASSERT); + } + case 119: break; + case 51: + { return createToken(OPERATOR_DECREMENT); + } + case 120: break; + case 15: + { return createToken(SEPARATOR_LBRACKET); + } + case 121: break; + case 104: + { return createToken(KEYWORD_CONTINUE); + } + case 122: break; + case 80: + { return createToken(KEYWORD_SHORT); + } + case 123: break; + case 26: + { return createToken(OPERATOR_BITWISE_AND); + } + case 124: break; + case 31: + { return createToken(OPERATOR_MOD); + } + case 125: break; + case 74: + { return createToken(KEYWORD_VOID); + } + case 126: break; + case 62: + { return createToken(OPERATOR_LSHIFT_EQUALS); + } + case 127: break; + case 38: + { return createToken(OPERATOR_EQUALS_EQUALS); + } + case 128: break; + case 69: + { return createToken(LITERAL_NULL); + } + case 129: break; + case 43: + { return createToken(OPERATOR_NE); + } + case 130: break; + case 28: + { return createToken(OPERATOR_PLUS); + } + case 131: break; + case 23: + { return createToken(OPERATOR_BITWISE_NOT); + } + case 132: break; + case 7: + { return createToken(SEPARATOR_DOT); + } + case 133: break; + case 102: + { return createToken(KEYWORD_ABSTRACT); + } + case 134: break; + case 92: + { return createToken(KEYWORD_NATIVE); + } + case 135: break; + case 35: + { return createToken(LITERAL_STRING); + } + case 136: break; + case 46: + { return createToken(OPERATOR_BITWISE_OR_EQUALS); + } + case 137: break; + case 60: + { return createToken(OPERATOR_RSHIFT_EQUALS); + } + case 138: break; + case 91: + { return createToken(KEYWORD_SWITCH); + } + case 139: break; + case 76: + { return createToken(KEYWORD_THROW); + } + case 140: break; + case 75: + { return createToken(OPERATOR_RSHIFT2_EQUALS); + } + case 141: break; + case 66: + { return createToken(KEYWORD_ELSE); + } + case 142: break; + case 3: + { if (returnWhitespace) { + return createToken(Token.WHITESPACE); + } + } + case 143: break; + case 54: + { return createToken(ELIPSIS); + } + case 144: break; + case 110: + { return createToken(KEYWORD_IMPLEMENTS); + } + case 145: break; + case 16: + { return createToken(SEPARATOR_RBRACKET); + } + case 146: break; + case 61: + { return createToken(OPERATOR_RSHIFT2); + } + case 147: break; + case 8: + { return createToken(LITERAL_CHAR, true); + } + case 148: break; + case 96: + { return createToken(KEYWORD_EXTENDS); + } + case 149: break; + case 84: + { return createToken(KEYWORD_CONST); + } + case 150: break; + case 94: + { return createToken(KEYWORD_DOUBLE); + } + case 151: break; + case 36: + { return createToken(KEYWORD_IF); + } + case 152: break; + case 83: + { return createToken(KEYWORD_CLASS); + } + case 153: break; + case 63: + { return createToken(LITERAL_FP); + } + case 154: break; + case 39: + { return createToken(OPERATOR_GTE); + } + case 155: break; + case 56: + { return createToken(KEYWORD_FOR); + } + case 156: break; + case 32: + { if (returnComments) { + return createToken(Token.COMMENT); + } + } + case 157: break; + case 70: + { return createToken(KEYWORD_BYTE); + } + case 158: break; + case 30: + { return createToken(OPERATOR_BITWISE_XOR); + } + case 159: break; + case 18: + { return createToken(SEPARATOR_COMMA); + } + case 160: break; + case 14: + { return createToken(SEPARATOR_RBRACE); + } + case 161: break; + case 41: + { return createToken(OPERATOR_LTE); + } + case 162: break; + case 57: + { return createToken(LITERAL_CHAR); + } + case 163: break; + case 58: + { return createToken(KEYWORD_NEW); + } + case 164: break; + case 48: + { return createToken(OPERATOR_PLUS_EQUALS); + } + case 165: break; + case 81: + { return createToken(KEYWORD_BREAK); + } + case 166: break; + case 1: + { return createToken(IDENTIFIER, true); + } + case 167: break; + case 9: + { return createToken(LITERAL_STRING, true); + } + case 168: break; + case 4: + { return createToken(OPERATOR_DIVIDE); + } + case 169: break; + case 29: + { return createToken(OPERATOR_MINUS); + } + case 170: break; + case 98: + { return createToken(KEYWORD_BOOLEAN); + } + case 171: break; + case 93: + { return createToken(KEYWORD_IMPORT); + } + case 172: break; + case 20: + { return createToken(OPERATOR_GT); + } + case 173: break; + case 47: + { return createToken(OPERATOR_LOGICAL_OR); + } + case 174: break; + case 2: + { return createToken(IDENTIFIER); + } + case 175: break; + case 53: + { return createToken(OPERATOR_MOD_EQUALS); + } + case 176: break; + case 100: + { return createToken(KEYWORD_PRIVATE); + } + case 177: break; + case 55: + { return createToken(KEYWORD_TRY); + } + case 178: break; + case 25: + { return createToken(OPERATOR_COLON); + } + case 179: break; + case 68: + { return createToken(KEYWORD_LONG); + } + case 180: break; + case 6: + { return createToken(LITERAL_INT); + } + case 181: break; + case 13: + { return createToken(SEPARATOR_LBRACE); + } + case 182: break; + case 45: + { return createToken(OPERATOR_LOGICAL_AND); + } + case 183: break; + case 21: + { return createToken(OPERATOR_LT); + } + case 184: break; + case 78: + { return createToken(KEYWORD_FINAL); + } + case 185: break; + case 24: + { return createToken(OPERATOR_QUESTION); + } + case 186: break; + case 19: + { return createToken(OPERATOR_EQUALS); + } + case 187: break; + case 108: + { return createToken(KEYWORD_PROTECTED); + } + case 188: break; + case 65: + { return createToken(KEYWORD_THIS); + } + case 189: break; + case 44: + { return createToken(OPERATOR_BITWISE_AND_EQUALS); + } + case 190: break; + case 109: + { return createToken(KEYWORD_INSTANCEOF); + } + case 191: break; + case 99: + { return createToken(KEYWORD_DEFAULT); + } + case 192: break; + case 40: + { return createToken(OPERATOR_RSHIFT); + } + case 193: break; + case 64: + { return createToken(LITERAL_BOOLEAN); + } + case 194: break; + case 67: + { return createToken(KEYWORD_ENUM); + } + case 195: break; + case 97: + { return createToken(KEYWORD_FINALLY); + } + case 196: break; + case 79: + { return createToken(KEYWORD_SUPER); + } + case 197: break; + case 77: + { return createToken(KEYWORD_FLOAT); + } + case 198: break; + case 101: + { return createToken(KEYWORD_PACKAGE); + } + case 199: break; + case 59: + { return createToken(KEYWORD_INT); + } + case 200: break; + case 22: + { return createToken(OPERATOR_LOGICAL_NOT); + } + case 201: break; + case 111: + { return createToken(KEYWORD_SYNCHRONIZED); + } + case 202: break; + case 73: + { return createToken(KEYWORD_GOTO); + } + case 203: break; + case 10: + { return createToken(ANNOTATION_START); + } + case 204: break; + case 12: + { return createToken(SEPARATOR_RPAREN); + } + case 205: break; + case 27: + { return createToken(OPERATOR_BITWISE_OR); + } + case 206: break; + case 49: + { return createToken(OPERATOR_INCREMENT); + } + case 207: break; + case 107: + { return createToken(KEYWORD_INTERFACE); + } + case 208: break; + case 88: + { return createToken(KEYWORD_RETURN); + } + case 209: break; + case 72: + { return createToken(KEYWORD_CHAR); + } + case 210: break; + case 17: + { return createToken(SEPARATOR_SEMICOLON); + } + case 211: break; + case 50: + { return createToken(OPERATOR_MINUS_EQUALS); + } + case 212: break; + case 33: + { return createToken(OPERATOR_DIVIDE_EQUALS); + } + case 213: break; + case 52: + { return createToken(OPERATOR_BITWISE_XOR_EQUALS); + } + case 214: break; + case 42: + { return createToken(OPERATOR_LSHIFT); + } + case 215: break; + case 103: + { return createToken(KEYWORD_STRICTFP); + } + case 216: break; + case 90: + { return createToken(KEYWORD_STATIC); + } + case 217: break; + case 85: + { return createToken(KEYWORD_WHILE); + } + case 218: break; + case 37: + { return createToken(KEYWORD_DO); + } + case 219: break; + case 106: + { return createToken(KEYWORD_TRANSIENT); + } + case 220: break; + case 86: + { if (keepLastDocComment) { + lastDocComment = yytext(); + } + if (returnComments) { + return createToken(Token.DOC_COMMENT); + } + } + case 221: break; + case 82: + { return createToken(KEYWORD_CATCH); + } + case 222: break; + default: + if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { + zzAtEOF = true; + return null; + } + else { + zzScanError(ZZ_NO_MATCH); + } + } + } + } + + +} diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/Token.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/Token.java new file mode 100644 index 00000000..a66d1d72 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/Token.java @@ -0,0 +1,55 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.rjc.lexer; + + +/** + * A lexical token in a Java file. + * + * @author Robert Futrell + * @version 0.1 + */ +public interface Token extends TokenTypes { + + public int getColumn(); + + + public String getLexeme(); + + + public int getLength(); + + + public int getLine(); + + + public int getOffset(); + + + public int getType(); + + + public boolean isBasicType(); + + + public boolean isIdentifier(); + + + public boolean isInvalid(); + + + public boolean isOperator(); + + + public boolean isType(int type); + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/TokenImpl.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/TokenImpl.java new file mode 100644 index 00000000..89cbf673 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/TokenImpl.java @@ -0,0 +1,167 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.rjc.lexer; + + +/** + * Implementation of a token in a Java source file. + * + * @author Robert Futrell + * @version 1.0 + */ +class TokenImpl implements Token { + + private int type; + + /** + * The token's text. + */ + private String lexeme; + + /** + * The line the token is on. + */ + private int line; + + /** + * The column the token is on. + */ + private int column; + + /** + * The absolute offset into the source of the token. + */ + private int offset; + + /** + * Whether the token is invalid (e.g. an invalid char of String). + */ + private boolean invalid; + + + public TokenImpl(int type, String lexeme, int line, int column, int offs) { + this(type, lexeme, line, column, offs, false); + } + + + public TokenImpl(int type, String lexeme, int line, int column, int offs, + boolean invalid) { + this.type = type; + this.lexeme = lexeme; + this.line = line; + this.column = column; + this.offset = offs; + this.invalid = invalid; + } + + + @Override + public boolean equals(Object obj) { + if (obj==this) { + return true; + } + if (obj instanceof Token) { + Token t2 = (Token)obj; + return type==t2.getType() && lexeme.equals(t2.getLexeme()) && + line==t2.getLine() && column==t2.getColumn() && + invalid==t2.isInvalid(); + } + return false; + } + + + public int getColumn() { + return column; + } + + + public int getLength() { + return lexeme.length(); + } + + + public String getLexeme() { + return lexeme; + } + + + public int getLine() { + return line; + } + + + public int getOffset() { + return offset; + } + + + public int getType() { + return type; + } + + + @Override + public int hashCode() { + return lexeme.hashCode(); + } + + + public boolean isBasicType() { + switch (getType()) { + case KEYWORD_BYTE: + case KEYWORD_SHORT: + case KEYWORD_CHAR: + case KEYWORD_INT: + case KEYWORD_LONG: + case KEYWORD_FLOAT: + case KEYWORD_DOUBLE: + case KEYWORD_BOOLEAN: + return true; + default: + return false; + } + } + + + public boolean isIdentifier() { + return (getType()&IDENTIFIER)>0; + } + + + public boolean isInvalid() { + return invalid; + } + + + public boolean isOperator() { + return (getType()&OPERATOR)>0; + } + + + public boolean isType(int type) { + return this.type==type; + } + + + @Override + public String toString() { + return "[TokenImpl: " + + "type=" + type + + "; lexeme=\"" + lexeme + "\"" + + "; line=" + getLine() + + "; col=" + getColumn() + + "; offs=" + getOffset() + + "; invalid=" + isInvalid() + + "]"; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/TokenTypes.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/TokenTypes.java new file mode 100644 index 00000000..90956af0 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/TokenTypes.java @@ -0,0 +1,141 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.rjc.lexer; + + +/** + * All possible token types returned by this lexer. + * + * @author Robert Futrell + * @version 1.0 + */ +public interface TokenTypes { + + public static final int KEYWORD = (0x01)<<16; + public static final int DATA_TYPE = (0x02|KEYWORD)<<16; + public static final int IDENTIFIER = (0x04)<<16; + public static final int COMMENT = (0x08)<<16; + public static final int DOC_COMMENT = (0x10|COMMENT)<<16; + public static final int WHITESPACE = (0x20)<<16; + public static final int LITERAL = (0x40)<<16; + public static final int SEPARATOR = (0x80)<<16; + public static final int OPERATOR = (0x100)<<16; + public static final int ASSIGNMENT_OPERATOR = (0x200|OPERATOR)<<16; + public static final int ANNOTATION_START = (0x400)<<16; + public static final int ELIPSIS = (0x800)<<16; + + public static final int KEYWORD_ABSTRACT = KEYWORD|1; + public static final int KEYWORD_ASSERT = KEYWORD|2; + public static final int KEYWORD_BOOLEAN = DATA_TYPE|3; + public static final int KEYWORD_BREAK = KEYWORD|4; + public static final int KEYWORD_BYTE = DATA_TYPE|5; + public static final int KEYWORD_CASE = KEYWORD|6; + public static final int KEYWORD_CATCH = KEYWORD|7; + public static final int KEYWORD_CHAR = DATA_TYPE|8; + public static final int KEYWORD_CLASS = KEYWORD|9; + public static final int KEYWORD_CONST = KEYWORD|10; + public static final int KEYWORD_CONTINUE = KEYWORD|11; + public static final int KEYWORD_DEFAULT = KEYWORD|12; + public static final int KEYWORD_DO = KEYWORD|13; + public static final int KEYWORD_DOUBLE = DATA_TYPE|14; + public static final int KEYWORD_ELSE = KEYWORD|15; + public static final int KEYWORD_ENUM = KEYWORD|16; + public static final int KEYWORD_EXTENDS = KEYWORD|17; + public static final int KEYWORD_FINAL = KEYWORD|18; + public static final int KEYWORD_FINALLY = KEYWORD|19; + public static final int KEYWORD_FLOAT = DATA_TYPE|20; + public static final int KEYWORD_FOR = KEYWORD|21; + public static final int KEYWORD_GOTO = KEYWORD|22; + public static final int KEYWORD_IF = KEYWORD|23; + public static final int KEYWORD_IMPLEMENTS = KEYWORD|24; + public static final int KEYWORD_IMPORT = KEYWORD|25; + public static final int KEYWORD_INSTANCEOF = KEYWORD|26; + public static final int KEYWORD_INT = DATA_TYPE|27; + public static final int KEYWORD_INTERFACE = KEYWORD|28; + public static final int KEYWORD_LONG = DATA_TYPE|29; + public static final int KEYWORD_NATIVE = KEYWORD|30; + public static final int KEYWORD_NEW = KEYWORD|31; + public static final int KEYWORD_PACKAGE = KEYWORD|32; + public static final int KEYWORD_PRIVATE = KEYWORD|33; + public static final int KEYWORD_PROTECTED = KEYWORD|34; + public static final int KEYWORD_PUBLIC = KEYWORD|35; + public static final int KEYWORD_RETURN = KEYWORD|36; + public static final int KEYWORD_SHORT = DATA_TYPE|37; + public static final int KEYWORD_STATIC = KEYWORD|38; + public static final int KEYWORD_STRICTFP = KEYWORD|39; + public static final int KEYWORD_SUPER = KEYWORD|40; + public static final int KEYWORD_SWITCH = KEYWORD|41; + public static final int KEYWORD_SYNCHRONIZED = KEYWORD|42; + public static final int KEYWORD_THIS = KEYWORD|43; + public static final int KEYWORD_THROW = KEYWORD|44; + public static final int KEYWORD_THROWS = KEYWORD|45; + public static final int KEYWORD_TRANSIENT = KEYWORD|46; + public static final int KEYWORD_TRY = KEYWORD|47; + public static final int KEYWORD_VOID = KEYWORD|48; + public static final int KEYWORD_VOLATILE = KEYWORD|49; + public static final int KEYWORD_WHILE = KEYWORD|50; + + public static final int LITERAL_INT = LITERAL|1; + public static final int LITERAL_FP = LITERAL|2; + public static final int LITERAL_BOOLEAN = LITERAL|3; + public static final int LITERAL_CHAR = LITERAL|4; + public static final int LITERAL_STRING = LITERAL|5; + public static final int LITERAL_NULL = LITERAL|6; + + public static final int SEPARATOR_LPAREN = SEPARATOR|1; + public static final int SEPARATOR_RPAREN = SEPARATOR|2; + public static final int SEPARATOR_LBRACE = SEPARATOR|3; + public static final int SEPARATOR_RBRACE = SEPARATOR|4; + public static final int SEPARATOR_LBRACKET = SEPARATOR|5; + public static final int SEPARATOR_RBRACKET = SEPARATOR|6; + public static final int SEPARATOR_SEMICOLON = SEPARATOR|7; + public static final int SEPARATOR_COMMA = SEPARATOR|8; + public static final int SEPARATOR_DOT = SEPARATOR|9; + + public static final int OPERATOR_EQUALS = ASSIGNMENT_OPERATOR|1; + public static final int OPERATOR_GT = OPERATOR|2; + public static final int OPERATOR_LT = OPERATOR|3; + public static final int OPERATOR_LOGICAL_NOT = OPERATOR|4; + public static final int OPERATOR_BITWISE_NOT = OPERATOR|5; + public static final int OPERATOR_QUESTION = OPERATOR|6; + public static final int OPERATOR_COLON = OPERATOR|7; + public static final int OPERATOR_EQUALS_EQUALS = OPERATOR|8; + public static final int OPERATOR_LTE = OPERATOR|9; + public static final int OPERATOR_GTE = OPERATOR|10; + public static final int OPERATOR_NE = OPERATOR|11; + public static final int OPERATOR_LOGICAL_AND = OPERATOR|12; + public static final int OPERATOR_LOGICAL_OR = OPERATOR|13; + public static final int OPERATOR_INCREMENT = OPERATOR|14; + public static final int OPERATOR_DECREMENT = OPERATOR|15; + public static final int OPERATOR_PLUS = OPERATOR|16; + public static final int OPERATOR_MINUS = OPERATOR|17; + public static final int OPERATOR_TIMES = OPERATOR|18; + public static final int OPERATOR_DIVIDE = OPERATOR|19; + public static final int OPERATOR_BITWISE_AND = OPERATOR|20; + public static final int OPERATOR_BITWISE_OR = OPERATOR|21; + public static final int OPERATOR_BITWISE_XOR = OPERATOR|22; + public static final int OPERATOR_MOD = OPERATOR|23; + public static final int OPERATOR_LSHIFT = OPERATOR|24; + public static final int OPERATOR_RSHIFT = OPERATOR|25; + public static final int OPERATOR_RSHIFT2 = OPERATOR|26; + public static final int OPERATOR_PLUS_EQUALS = ASSIGNMENT_OPERATOR|27; + public static final int OPERATOR_MINUS_EQUALS = ASSIGNMENT_OPERATOR|28; + public static final int OPERATOR_TIMES_EQUALS = ASSIGNMENT_OPERATOR|29; + public static final int OPERATOR_DIVIDE_EQUALS = ASSIGNMENT_OPERATOR|30; + public static final int OPERATOR_BITWISE_AND_EQUALS = ASSIGNMENT_OPERATOR|31; + public static final int OPERATOR_BITWISE_OR_EQUALS = ASSIGNMENT_OPERATOR|32; + public static final int OPERATOR_BITWISE_XOR_EQUALS = ASSIGNMENT_OPERATOR|33; + public static final int OPERATOR_MOD_EQUALS = ASSIGNMENT_OPERATOR|34; + public static final int OPERATOR_LSHIFT_EQUALS = ASSIGNMENT_OPERATOR|35; + public static final int OPERATOR_RSHIFT_EQUALS = ASSIGNMENT_OPERATOR|36; + public static final int OPERATOR_RSHIFT2_EQUALS = ASSIGNMENT_OPERATOR|37; + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/notices/ParserNotice.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/notices/ParserNotice.java new file mode 100644 index 00000000..4f2da8fa --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/rjc/notices/ParserNotice.java @@ -0,0 +1,106 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.rjc.notices; + +import org.fife.rsta.ac.bsh.rjc.lexer.Token; + + +/** + * A notice (e.g., a warning or error) from a parser. + * + * @author Robert Futrell + * @version 0.1 + */ +public class ParserNotice { + + private int line; + private int column; + private int length; + private String message; + + + public ParserNotice(Token t, String msg) { + line = t.getLine(); + column = t.getColumn(); + length = t.getLexeme().length(); + message = msg; + } + + + /** + * Constructor. + * + * @param line The line of the notice. + * @param column The column of the notice. + * @param length The length of the code the message is concerned with. + * @param message The message. + */ + public ParserNotice(int line, int column, int length, String message) { + this.line = line; + this.column = column; + this.length = length; + this.message = message; + } + + + /** + * Returns the character offset into the line of the parser notice, + * if any. + * + * @return The column. + */ + public int getColumn() { + return column; + } + + + /** + * Returns the length of the code the message is concerned with. + * + * @return The length of the code the message is concerned with. + */ + public int getLength() { + return length; + } + + + /** + * Returns the line number the notice is about, if any. + * + * @return The line number. + */ + public int getLine() { + return line; + } + + + /** + * Returns the message from the parser. + * + * @return The message from the parser. + */ + public String getMessage() { + return message; + } + + + /** + * Returns a string representation of this parser notice. + * + * @return This parser notice as a string. + */ + @Override + public String toString() { + return "(" + getLine() + ", " + getColumn() + ": " + getMessage(); + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/parser/ASTFactory.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/parser/ASTFactory.java new file mode 100644 index 00000000..eef3b39b --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/rjc/parser/ASTFactory.java @@ -0,0 +1,888 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.rjc.parser; + +import org.fife.rsta.ac.bsh.rjc.lexer.Token; +import org.fife.rsta.ac.bsh.rjc.lexer.Scanner; +import org.fife.rsta.ac.bsh.rjc.lexer.TokenTypes; +import java.io.EOFException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.fife.rsta.ac.bsh.rjc.ast.CodeBlock; +import org.fife.rsta.ac.bsh.rjc.ast.CompilationUnit; +import org.fife.rsta.ac.bsh.rjc.ast.FormalParameter; +import org.fife.rsta.ac.bsh.rjc.ast.ImportDeclaration; +import org.fife.rsta.ac.bsh.rjc.ast.LocalVariable; +import org.fife.rsta.ac.bsh.rjc.ast.Method; +import org.fife.rsta.ac.bsh.rjc.ast.NormalClassDeclaration; +import org.fife.rsta.ac.bsh.rjc.ast.Package; +import org.fife.rsta.ac.bsh.rjc.ast.TypeDeclaration; +import org.fife.rsta.ac.bsh.rjc.ast.TypeDeclarationContainer; +import org.fife.rsta.ac.bsh.rjc.lang.Annotation; +import org.fife.rsta.ac.bsh.rjc.lang.Modifiers; +import org.fife.rsta.ac.bsh.rjc.lang.Type; +import org.fife.rsta.ac.bsh.rjc.lang.TypeArgument; +import org.fife.rsta.ac.bsh.rjc.notices.ParserNotice; + +/** + * Generates an abstract syntax tree for a Java source file. + * + * @author Robert Futrell + * @version 1.0 + */ +public class ASTFactory implements TokenTypes { + + private static final boolean DEBUG = false; + + public ASTFactory() { + } + + /** + * Checks whether a local variable's name collides with a local variable + * defined earlier. Note that this method assumes that it is called + * immediately whenever a variable is parsed, thus any other variables + * declared in a code block were declared before the one being checked. + * + * @param cu The compilation unit. + * @param lVar The just-scanned local variable. + * @param block The code block the variable is in. + * @param m The method the (possibly nested) code block block + * is in, or null for none. + */ + private void checkForDuplicateLocalVarNames(CompilationUnit cu, + Token lVar, CodeBlock block, Method m) { + + String name = lVar.getLexeme(); + boolean found = false; + + // See if a local variable defined previously in this block has the + // same name. + for (int i = 0; i < block.getLocalVarCount(); i++) { + LocalVariable otherLocal = block.getLocalVar(i); + if (name.equals(otherLocal.getName())) { + cu.addParserNotice(lVar, "Duplicate local variable: " + name); + found = true; + break; + } + } + + // If not... + if (!found) { + + // If this was a nested code block, check previously-defined + // variables in the parent block. + if (block.getParent() != null) { + checkForDuplicateLocalVarNames(cu, lVar, block.getParent(), m); + } // If this was the highest-level code block, if we're in the body + // of a method, check the method's parameters. + else if (m != null) { + for (int i = 0; i < m.getParameterCount(); i++) { + FormalParameter param = m.getParameter(i); + if (name.equals(param.getName())) { + cu.addParserNotice(lVar, "Duplicate local variable: " + name); + break; + } + } + } + + } + + } + + /** + * Assumes t is the actual '@foobar' annotation token. + * + * @param cu + * @param s + * @return + * @throws IOException + */ + private Annotation _getAnnotation(CompilationUnit cu, Scanner s) + throws IOException { + + s.yylexNonNull(ANNOTATION_START, "Annotation expected"); + Type type = _getType(cu, s); + + if (s.yyPeekCheckType() == SEPARATOR_LPAREN) { + s.yylex(); + // TODO: Read rest of Annotation stuff + s.eatThroughNextSkippingBlocks(SEPARATOR_RPAREN); + } + + Annotation a = new Annotation(type); + return a; + + } + + private CodeBlock _getScript(CompilationUnit cu, CodeBlock parent, Method m, + Scanner s, boolean isStatic) throws IOException { + return _getScript(cu, parent, m, s, isStatic, 1); + } + + /** + * Parses a block of code. This should not be called. + * + * @param parent The parent code block, or null if none (i.e. + * this is the body of a method, a static initializer block, etc.). + * @param m The method containing this block, or null if this + * block is not part of a method. + * @param s The scanner. + * @param isStatic Whether this is a static code block. + * @param depth The nested depth of this code block. + */ + private CodeBlock _getBlock(CompilationUnit cu, CodeBlock parent, + Method m, Scanner s, + boolean isStatic, int depth) throws IOException { + + log("Entering _getBlock() (" + depth + ")"); + + // TODO: Implement me to get variable declarations. + Token t = s.yylexNonNull(SEPARATOR_LBRACE, "'{' expected"); + CodeBlock block = new CodeBlock(isStatic, s.createOffset(t.getOffset())); + block.setParent(parent); + boolean atStatementStart = true; + + OUTER: + while (true) { + + // Don't bail if they have unmatched parens (for example), just + // return the current status of the block. + //t = s.yylexNonNull("Unexpected end of input"); + if ((t = s.yylex()) == null) { + log("Exiting _getBlock() - eos (" + depth + ")"); + block.setDeclarationEndOffset(s.createOffset(s.getOffset())); + return block; + } + + int type = t.getType(); + boolean isFinal = false; + + switch (type) { + + case SEPARATOR_LBRACE: + s.yyPushback(t); + CodeBlock child = _getBlock(cu, block, m, s, isStatic, depth + 1); + block.add(child); + atStatementStart = true; + break; + + case SEPARATOR_RBRACE: + block.setDeclarationEndOffset(s.createOffset(t.getOffset())); + break OUTER; + + case KEYWORD_TRY: + t = s.yyPeekNonNull(SEPARATOR_LBRACE, SEPARATOR_LPAREN, "'{' or '(' expected"); + if (t.getType() == SEPARATOR_LPAREN) { // Auto-closeable stuff + // TODO: Get block-scoped var(s) + s.eatParenPairs(); + } + s.yyPeekNonNull(SEPARATOR_LBRACE, "'{' expected"); + CodeBlock tryBlock = _getBlock(cu, block, m, s, isStatic, depth + 1); + block.add(tryBlock); + while (s.yyPeekCheckType() == KEYWORD_CATCH + && s.yyPeekCheckType(2) == SEPARATOR_LPAREN) { + s.yylex(); // catch + s.yylex(); // lparen + Type exType = null; + Token var = null; + boolean multiCatch = false; + do { + isFinal = false; + Token temp = s.yyPeekNonNull(IDENTIFIER, KEYWORD_FINAL, "Throwable type expected"); + if (temp.isType(KEYWORD_FINAL)) { + isFinal = true; + s.yylex(); + } + s.yyPeekNonNull(IDENTIFIER, "Variable declarator expected"); + exType = _getType(cu, s); // Not good for multi-catch! + var = s.yylexNonNull(IDENTIFIER, OPERATOR_BITWISE_OR, "Variable declarator expected"); + multiCatch |= var.isType(OPERATOR_BITWISE_OR); + } while (var.isType(OPERATOR_BITWISE_OR)); + s.yylexNonNull(SEPARATOR_RPAREN, "')' expected"); + s.yyPeekNonNull(SEPARATOR_LBRACE, "'{' expected"); + CodeBlock catchBlock = _getBlock(cu, block, m, s, false, depth); + int offs = var.getOffset(); // Not actually in block! + if (multiCatch) { + // TODO: With Java 7's multi-catch, calculate + // least upper bound for exception type: + // http://cr.openjdk.java.net/~darcy/ProjectCoin/ProjectCoin-Documentation-v0.83.html#multi_catch + exType = new Type("java"); + exType.addIdentifier("lang", null); + exType.addIdentifier("Throwable", null); + } + LocalVariable localVar = new LocalVariable(s, isFinal, exType, offs, var.getLexeme()); + checkForDuplicateLocalVarNames(cu, var, block, m); + catchBlock.addLocalVariable(localVar); + block.add(catchBlock); + } + break; + + case KEYWORD_FOR: + // TODO: Get local var (e.g. "int i", "Iterator i", etc.) + // Fall through + case KEYWORD_WHILE: + int nextType = s.yyPeekCheckType(); + while (nextType != -1 && nextType != SEPARATOR_LPAREN) { + t = s.yylex(); // Grab the (unexpected) token + if (t != null) { // Should always be true + ParserNotice pn = new ParserNotice(t, "Unexpected token"); + cu.addParserNotice(pn); + } + nextType = s.yyPeekCheckType(); + } + if (nextType == SEPARATOR_LPAREN) { + s.eatParenPairs(); + } + nextType = s.yyPeekCheckType(); + if (nextType == SEPARATOR_LBRACE) { + child = _getBlock(cu, block, m, s, isStatic, depth + 1); + block.add(child); + atStatementStart = true; + } + break; + +// NOTE: The code below is supposed to try to parse code blocks and identify +// variable declarations. This does work somewhat, but the problem is that +// our parsing of type parameters isn't good enough, and lines like: +// for (int i=0; i" (even though the closing '>' isn't +// there, but that's not the big problem really!). We should be able to check +// whether our type parameters are well-formed, and if they aren't, then assume +// push all tokens back, and assume that the '<' was a less-than operator. +// It's the "push all tokens back" that's tough for us at the moment, as we've +// lost most of the tokens (there may be an arbitrary number that have been +// parsed and discarded). + case KEYWORD_FINAL: + isFinal = true; + t = s.yylexNonNull("Unexpected end of file"); + // Fall through + + default: + if (t.isType(SEPARATOR_SEMICOLON)) { + atStatementStart = true; + break; + } else if (atStatementStart && (t.isBasicType() || (t.isIdentifier()))) { + s.yyPushback(t); + // TODO: This is very inefficient + Type varType = null; + try { + varType = _getType(cu, s, true); + } catch (IOException ioe) { // Not a var declaration + s.eatUntilNext(SEPARATOR_SEMICOLON, SEPARATOR_LBRACE, SEPARATOR_RBRACE); + // Only needed if ended on ';' or '}', but... + atStatementStart = true; + break; + } + if (s.yyPeekCheckType() == IDENTIFIER) { + while ((t = s.yylexNonNull(IDENTIFIER, "Variable name expected (type==" + varType.toString() + ")")) != null) { + int arrayDepth = s.skipBracketPairs(); + varType.incrementBracketPairCount(arrayDepth); + String varDec = varType.toString() + " " + t.getLexeme(); + log(">>> Variable -- " + varDec + " (line " + t.getLine() + ")"); + int offs = t.getOffset(); + String name = t.getLexeme(); + LocalVariable lVar = new LocalVariable(s, isFinal, varType, offs, name); + checkForDuplicateLocalVarNames(cu, t, block, m); + block.addLocalVariable(lVar); + nextType = s.yyPeekCheckType(); + // A "valid" nextType would be '=', ',' or ';'. + // If it's an '=', skip past the assignment. + if (nextType == OPERATOR_EQUALS) { + Token temp = s.eatThroughNextSkippingBlocksAndStuffInParens(SEPARATOR_COMMA, SEPARATOR_SEMICOLON); + if (temp != null) { + s.yyPushback(temp); + } + nextType = s.yyPeekCheckType(); + } + // If next is a comma, loop to read the next local + // var. Otherwise, whether or not it's valid, + // eat until the end of the statement. + if (nextType != SEPARATOR_COMMA) { + s.eatThroughNextSkippingBlocks(SEPARATOR_SEMICOLON); + break; + } + s.yylex(); // Eat the comma (does nothing if EOS) + } + } + } else { + atStatementStart = false; + } + break; + + } + + } + + log("Exiting _getBlock() (" + depth + ")"); + return block; + + } + + private CodeBlock _getScript(CompilationUnit cu, CodeBlock parent, + Method m, Scanner s, + boolean isStatic, int depth) throws IOException { + + log("Entering _getScript() (" + depth + ")"); + + // TODO: Implement me to get variable declarations. + Token t = s.yyPeek(); + CodeBlock block = new CodeBlock(isStatic, s.createOffset(t.getOffset())); + block.setParent(parent); + boolean atStatementStart = true; + + OUTER: + while (true) { + + // Don't bail if they have unmatched parens (for example), just + // return the current status of the block. + //t = s.yylexNonNull("Unexpected end of input"); + if ((t = s.yylex()) == null) { + log("Exiting _getScript() - eos (" + depth + ")"); + block.setDeclarationEndOffset(s.createOffset(s.getOffset())); + return block; + } + + int type = t.getType(); + boolean isFinal = false; + + switch (type) { + + case SEPARATOR_LBRACE: + s.yyPushback(t); + CodeBlock child = _getBlock(cu, block, m, s, isStatic, depth + 1); + block.add(child); + atStatementStart = true; + break; + + case SEPARATOR_RBRACE: + block.setDeclarationEndOffset(s.createOffset(t.getOffset())); + break OUTER; + + case KEYWORD_TRY: + t = s.yyPeekNonNull(SEPARATOR_LBRACE, SEPARATOR_LPAREN, "'{' or '(' expected"); + if (t.getType() == SEPARATOR_LPAREN) { // Auto-closeable stuff + // TODO: Get block-scoped var(s) + s.eatParenPairs(); + } + s.yyPeekNonNull(SEPARATOR_LBRACE, "'{' expected"); + CodeBlock tryBlock = _getBlock(cu, block, m, s, isStatic, depth + 1); + block.add(tryBlock); + while (s.yyPeekCheckType() == KEYWORD_CATCH + && s.yyPeekCheckType(2) == SEPARATOR_LPAREN) { + s.yylex(); // catch + s.yylex(); // lparen + Type exType = null; + Token var = null; + boolean multiCatch = false; + do { + isFinal = false; + Token temp = s.yyPeekNonNull(IDENTIFIER, KEYWORD_FINAL, "Throwable type expected"); + if (temp.isType(KEYWORD_FINAL)) { + isFinal = true; + s.yylex(); + } + s.yyPeekNonNull(IDENTIFIER, "Variable declarator expected"); + exType = _getType(cu, s); // Not good for multi-catch! + var = s.yylexNonNull(IDENTIFIER, OPERATOR_BITWISE_OR, "Variable declarator expected"); + multiCatch |= var.isType(OPERATOR_BITWISE_OR); + } while (var.isType(OPERATOR_BITWISE_OR)); + s.yylexNonNull(SEPARATOR_RPAREN, "')' expected"); + s.yyPeekNonNull(SEPARATOR_LBRACE, "'{' expected"); + CodeBlock catchBlock = _getBlock(cu, block, m, s, false, depth); + int offs = var.getOffset(); // Not actually in block! + if (multiCatch) { + // TODO: With Java 7's multi-catch, calculate + // least upper bound for exception type: + // http://cr.openjdk.java.net/~darcy/ProjectCoin/ProjectCoin-Documentation-v0.83.html#multi_catch + exType = new Type("java"); + exType.addIdentifier("lang", null); + exType.addIdentifier("Throwable", null); + } + LocalVariable localVar = new LocalVariable(s, isFinal, exType, offs, var.getLexeme()); + checkForDuplicateLocalVarNames(cu, var, block, m); + catchBlock.addLocalVariable(localVar); + block.add(catchBlock); + } + break; + + case KEYWORD_FOR: + // TODO: Get local var (e.g. "int i", "Iterator i", etc.) + // Fall through + case KEYWORD_WHILE: + int nextType = s.yyPeekCheckType(); + while (nextType != -1 && nextType != SEPARATOR_LPAREN) { + t = s.yylex(); // Grab the (unexpected) token + if (t != null) { // Should always be true + ParserNotice pn = new ParserNotice(t, "Unexpected token"); + cu.addParserNotice(pn); + } + nextType = s.yyPeekCheckType(); + } + if (nextType == SEPARATOR_LPAREN) { + s.eatParenPairs(); + } + nextType = s.yyPeekCheckType(); + if (nextType == SEPARATOR_LBRACE) { + child = _getBlock(cu, block, m, s, isStatic, depth + 1); + block.add(child); + atStatementStart = true; + } + break; + +// NOTE: The code below is supposed to try to parse code blocks and identify +// variable declarations. This does work somewhat, but the problem is that +// our parsing of type parameters isn't good enough, and lines like: +// for (int i=0; i" (even though the closing '>' isn't +// there, but that's not the big problem really!). We should be able to check +// whether our type parameters are well-formed, and if they aren't, then assume +// push all tokens back, and assume that the '<' was a less-than operator. +// It's the "push all tokens back" that's tough for us at the moment, as we've +// lost most of the tokens (there may be an arbitrary number that have been +// parsed and discarded). + case KEYWORD_FINAL: + isFinal = true; + t = s.yylexNonNull("Unexpected end of file"); + // Fall through + + default: + if (t.isType(SEPARATOR_SEMICOLON)) { + atStatementStart = true; + break; + } else if (atStatementStart && (t.isBasicType() || (t.isIdentifier()))) { + s.yyPushback(t); + // TODO: This is very inefficient + Type varType = null; + try { + varType = _getType(cu, s, true); + } catch (IOException ioe) { // Not a var declaration + s.eatUntilNext(SEPARATOR_SEMICOLON, SEPARATOR_LBRACE, SEPARATOR_RBRACE); + // Only needed if ended on ';' or '}', but... + atStatementStart = true; + break; + } + if (s.yyPeekCheckType() == IDENTIFIER) { + while ((t = s.yylexNonNull(IDENTIFIER, "Variable name expected (type==" + varType.toString() + ")")) != null) { + int arrayDepth = s.skipBracketPairs(); + varType.incrementBracketPairCount(arrayDepth); + String varDec = varType.toString() + " " + t.getLexeme(); + log(">>> Variable -- " + varDec + " (line " + t.getLine() + ")"); + int offs = t.getOffset(); + String name = t.getLexeme(); + LocalVariable lVar = new LocalVariable(s, isFinal, varType, offs, name); + checkForDuplicateLocalVarNames(cu, t, block, m); + block.addLocalVariable(lVar); + nextType = s.yyPeekCheckType(); + // A "valid" nextType would be '=', ',' or ';'. + // If it's an '=', skip past the assignment. + if (nextType == OPERATOR_EQUALS) { + Token temp = s.eatThroughNextSkippingBlocksAndStuffInParens(SEPARATOR_COMMA, SEPARATOR_SEMICOLON); + if (temp != null) { + s.yyPushback(temp); + } + nextType = s.yyPeekCheckType(); + } + // If next is a comma, loop to read the next local + // var. Otherwise, whether or not it's valid, + // eat until the end of the statement. + if (nextType != SEPARATOR_COMMA) { + s.eatThroughNextSkippingBlocks(SEPARATOR_SEMICOLON); + break; + } + s.yylex(); // Eat the comma (does nothing if EOS) + } + } + } else { + atStatementStart = false; + } + break; + + } + + } + + log("Exiting _getScript() (" + depth + ")"); + return block; + + } + + private TypeDeclaration _getClassOrInterfaceDeclaration(CompilationUnit cu, + Scanner s, TypeDeclarationContainer addTo, Modifiers modList) + throws IOException { + + log("Entering _getClassOrInterfaceDeclaration"); + + TypeDeclaration td = _getNormalClassDeclaration(cu, s, addTo); + + log("Exiting _getClassOrInterfaceDeclaration"); + return td; + + } + + /** + * Reads tokens for a Java source file from the specified lexer and returns + * the structure of the source as an AST. + * + * @param scanner The scanner to read from. + * @return The root node of the AST. + */ + public CompilationUnit getCompilationUnit(String name, Scanner scanner) + throws IOException { + + CompilationUnit cu = new CompilationUnit(name); + + try { + + // Get annotations. + List initialAnnotations = null; // Usually none + while (scanner.yyPeekCheckType() == ANNOTATION_START) { + if (initialAnnotations == null) { + initialAnnotations = new ArrayList(1); + } + initialAnnotations.add(_getAnnotation(cu, scanner)); + } + + // Get possible "package" line. + Token t = scanner.yylex(); + if (t == null) { + return cu; + } + if (t.isType(KEYWORD_PACKAGE)) { + t = scanner.yyPeekNonNull("Identifier expected"); + int offs = t.getOffset(); + String qualifiedID = getQualifiedIdentifier(scanner); + Package pkg = new Package(scanner, offs, qualifiedID); + if (initialAnnotations != null) { + // pkg.setAnnotations(initialAnnotations); + initialAnnotations = null; + } + cu.setPackage(pkg); + scanner.yylexNonNull(SEPARATOR_SEMICOLON, "Semicolon expected"); + t = scanner.yylex(); + } + + // Go through any import statements. + OUTER: + while (t != null && t.isType(KEYWORD_IMPORT)) { + + boolean isStatic = false; + StringBuilder buf = new StringBuilder(); + t = scanner.yylexNonNull("Incomplete import statement"); + Token temp = null; + int offs = 0; + + if (t.isType(KEYWORD_STATIC)) { + isStatic = true; + t = scanner.yylexNonNull("Incomplete import statement"); + } + + if (!t.isIdentifier()) { + cu.addParserNotice(t, "Expected identifier, found: \"" + + t.getLexeme() + "\""); + scanner.eatThroughNextSkippingBlocks(SEPARATOR_SEMICOLON); + // We expect "t" to be the semicolon below + t = scanner.getMostRecentToken(); + } else { + offs = t.getOffset(); + buf.append(t.getLexeme()); + temp = scanner.yylexNonNull(SEPARATOR_DOT, SEPARATOR_SEMICOLON, + "'.' or ';' expected"); + while (temp.isType(SEPARATOR_DOT)) { + temp = scanner.yylexNonNull(IDENTIFIER, OPERATOR_TIMES, + "Identifier or '*' expected"); + if (temp.isIdentifier()) { + buf.append('.').append(temp.getLexeme()); + } else {//if (temp.getLexeme().equals("*")) { + buf.append(".*"); + temp = scanner.yylex(); // We're bailing, so scan here + break; + } + temp = scanner.yylexNonNull(KEYWORD_IMPORT, SEPARATOR_DOT, + SEPARATOR_SEMICOLON, "'.' or ';' expected"); + if (temp.isType(KEYWORD_IMPORT)) { + cu.addParserNotice(temp, "';' expected"); + t = temp; + continue OUTER; + } + } + t = temp; + } + + if (temp == null || !t.isType(SEPARATOR_SEMICOLON)) { + throw new IOException("Semicolon expected, found " + t); + } + + ImportDeclaration id = new ImportDeclaration(scanner, offs, + buf.toString(), isStatic); + cu.addImportDeclaration(id); + t = scanner.yylex(); + + } + + // class files aren't required to have TypeDeclarations. + if (t == null) { + return cu; + } + + scanner.yyPushback(t); + //TypeDeclaration td = null; + while ((/*td = */_getTypeDeclaration(cu, scanner)) != null) { + if (initialAnnotations != null) { + // td.addAnnotations(initialAnnotations); + initialAnnotations = null; + } +// cu.addTypeDeclaration(td); +// Done when the type declarations are created. + } + + } catch (IOException ioe) { + if (isDebug() && !(ioe instanceof EOFException)) { // Not just "end of file" + ioe.printStackTrace(); + } + ParserNotice notice = null; + Token lastTokenLexed = scanner.getMostRecentToken(); + if (lastTokenLexed == null) { + notice = new ParserNotice(0, 0, 5, ioe.getMessage()); + } else { + notice = new ParserNotice(lastTokenLexed, ioe.getMessage()); + } + cu.addParserNotice(notice); +//throw ioe; // Un-comment me to get the AnnotationTypeDeclaration error count in "Main" test + } + + return cu; + + } + + private NormalClassDeclaration _getNormalClassDeclaration( + CompilationUnit cu, Scanner s, TypeDeclarationContainer addTo) + throws IOException { + + log("Entering _getNormalClassDeclaration"); + + Token t = s.yylexNonNull("Identifier expected"); + s.yyPushback(t); + + NormalClassDeclaration classDec = new NormalClassDeclaration(s, + t.getOffset(), "BSH_SCRIPT"); + classDec.setPackage(cu.getPackage()); + addTo.addTypeDeclaration(classDec); + CodeBlock block = _getScript(cu, null, null, s, true); + classDec.addMember(block); + + log("Exiting _getNormalClassDeclaration"); + return classDec; + + } + + private String getQualifiedIdentifier(Scanner scanner) + throws IOException { + + Token t = null; + StringBuilder sb = new StringBuilder(); + + while ((t = scanner.yylex()).isIdentifier()) { + sb.append(t.getLexeme()); + t = scanner.yylex(); + if (t.isType(SEPARATOR_DOT)) { + sb.append('.'); + } else { + break; + } + } + + // QualifiedIdentifier has ended. + scanner.yyPushback(t); + + return sb.toString(); + + } + + // For "backwards compatibility," don't know if "false" is usually + // correct or not + private Type _getType(CompilationUnit cu, Scanner s) throws IOException { + return _getType(cu, s, false); + } + + private Type _getType(CompilationUnit cu, Scanner s, + boolean pushbackOnUnexpected) throws IOException { + + log("Entering _getType()"); + Type type = new Type(); + + Token t = s.yylexNonNull("Type expected"); + + // TODO: "void" checking is NOT in the JLS for type! Remove me + if (t.isType(KEYWORD_VOID)) { + type.addIdentifier(t.getLexeme(), null); + log("Exiting _getType(): " + type.toString()); + return type; + } else if (t.isBasicType()) { + int arrayDepth = s.skipBracketPairs(); + type.addIdentifier(t.getLexeme(), null); + type.setBracketPairCount(arrayDepth); + log("Exiting _getType(): " + type.toString()); + return type; + } + + OUTER: + while (true) { + switch (t.getType()) { + case IDENTIFIER: + List typeArgs = null; + if (s.yyPeekCheckType() == OPERATOR_LT) { + typeArgs = _getTypeArguments(cu, s); + } + type.addIdentifier(t.getLexeme(), typeArgs); + t = s.yylexNonNull("Unexpected end of input"); + if (t.isType(SEPARATOR_DOT)) { + t = s.yylexNonNull("Unexpected end of input"); + continue; + } else if (t.isType(SEPARATOR_LBRACKET)) { + s.yyPushback(t); + type.setBracketPairCount(s.skipBracketPairs()); + break OUTER; + } else { + s.yyPushback(t); + break OUTER; + } + default: + if (pushbackOnUnexpected) { + s.yyPushback(t); + } + throw new IOException("Expected identifier, found: " + t); + } + } + + log("Exiting _getType(): " + type.toString()); + return type; + + } + + private TypeArgument _getTypeArgument(CompilationUnit cu, Scanner s) + throws IOException { + + log("Entering _getTypeArgument()"); + + TypeArgument typeArg = null; + + Token t = s.yyPeekNonNull("Type or '?' expected"); + + if (t.isType(OPERATOR_QUESTION)) { + s.yylex(); // Pop the '?' off the stream. + t = s.yyPeek(); + if (t.getType() != OPERATOR_GT) { + t = s.yylexNonNull(SEPARATOR_COMMA, KEYWORD_EXTENDS, + KEYWORD_SUPER, + "',', super or extends expected"); + switch (t.getType()) { + case SEPARATOR_COMMA: + typeArg = new TypeArgument(null, 0, null); + s.yyPushback(t); + break; + case KEYWORD_EXTENDS: + Type otherType = _getType(cu, s); + typeArg = new TypeArgument(null, TypeArgument.EXTENDS, otherType); + break; + default: // KEYWORD_SUPER: + otherType = _getType(cu, s); + typeArg = new TypeArgument(null, TypeArgument.SUPER, otherType); + break; + } + } else { + typeArg = new TypeArgument(null, 0, null); + } + } else { + Type type = _getType(cu, s); + typeArg = new TypeArgument(type); + } + + log("Exiting _getTypeArgument() : " + typeArg); + return typeArg; + + } + + private List _getTypeArguments(CompilationUnit cu, Scanner s) + throws IOException { + + s.increaseTypeArgumentsLevel(); + log("Entering _getTypeArguments() (" + s.getTypeArgumentsLevel() + ")"); + + s.markResetPosition(); + s.yylexNonNull(OPERATOR_LT, "'<' expected"); + + List typeArgs = new ArrayList(1); + + Token t = null; + do { + typeArgs.add(_getTypeArgument(cu, s)); + t = s.yylexNonNull("',' or '>' expected"); + if (t.getType() != SEPARATOR_COMMA && t.getType() != OPERATOR_GT) { + // Assume we're in a code block, and are simply at the (much + // more common) case of e.g. "if (i < 7) ...". + s.resetToLastMarkedPosition(); + log("Exiting _getTypeArguments() (" + s.getTypeArgumentsLevel() + ") - NOT TYPE ARGUMENTS (" + t.getLexeme() + ")"); + s.decreaseTypeArgumentsLevel(); + return null; + } + } while (t.isType(SEPARATOR_COMMA)); + + log("Exiting _getTypeArguments() (" + s.getTypeArgumentsLevel() + ")"); + s.decreaseTypeArgumentsLevel(); + + s.clearResetPosition(); + return typeArgs; + + } + + private TypeDeclaration _getTypeDeclaration(CompilationUnit cu, + Scanner s) throws IOException { + + /* + * TypeDeclaration: + * ClassOrInterfaceDeclaration + * ';' + */ + Token t = s.yylex(); + if (t == null) { + return null; // End of source file. + } + + // Skip any semicolons. + while (t.isType(SEPARATOR_SEMICOLON)) { + t = s.yylex(); + if (t == null) { + return null; // End of source file + } + } + + s.yyPushback(t); // Probably some modifier, e.g. "public" + + String docComment = s.getLastDocComment(); + TypeDeclaration td = _getClassOrInterfaceDeclaration(cu, s, cu, null); + td.setDocComment(docComment); // May be null + return td; + + } + + private static final boolean isDebug() { + return DEBUG; + } + + private static final void log(String msg) { + if (DEBUG) { + System.out.println(msg); + } + } + +} diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/parser/Main.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/parser/Main.java new file mode 100644 index 00000000..1569715f --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/rjc/parser/Main.java @@ -0,0 +1,141 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.rjc.parser; + +import org.fife.rsta.ac.bsh.rjc.lexer.Scanner; +import java.io.*; +import java.util.ArrayList; +import java.util.List; + + + +/** + * Test application for the Java scanner. + * + * @author Robert Futrell + * @version 1.0 + */ +public class Main { + + /** + * If this system property is set to "true", + * output will not be written to stdout for each file. + */ + public static final String PROPERTY_NO_OUTPUT = "no.output"; + + private static final boolean LOG = !"true".equals( + System.getProperty(PROPERTY_NO_OUTPUT)); + + + private static void log(Object text) { + if (LOG) { + System.out.println(text); + } + } + + + /** + * Program entry point. + * + * @param args Command line arguments. + * @throws IOException If an IO error occurs. + */ + public static void main(String[] args) throws IOException { + +PrintStream oldOut = System.out; +PrintStream oldErr = System.err; +//PrintStream out = new PrintStream(new BufferedOutputStream(new FileOutputStream("C:/temp/rofutr.out"))); +//System.setOut(out); +//System.setErr(out); + + ASTFactory fact = new ASTFactory(); + //CompilationUnit cu = null; + + List toDo = new ArrayList(); + + if (args.length>0) { + toDo.add(new File(args[0])); + } + else { +//toDo.add(new File("C:\\java\\32\\jdk1.6.0_16\\src\\java\\util\\concurrent\\TimeUnit.java")); + File rootDir = new File("C:/java/32/jdk1.6.0_16/src/"); +//rootDir = new File("C:/dev/rsta/JavaAst/src"); +//rootDir = new File("C:/dev/rjava/Common/src"); + File[] files = rootDir.listFiles(); + for (int i=0; i + * + * You can get this tree automatically updating in response to edits in an + * RSyntaxTextArea with {@link JavaLanguageSupport} installed by + * calling {@link #listenTo(RSyntaxTextArea)}. Note that an instance of this + * class can only listen to a single editor at a time, so if your application + * contains multiple instances of RSyntaxTextArea, you'll either need a separate + * JavaOutlineTree for each one, or call uninstall() + * and listenTo(RSyntaxTextArea) each time a new RSTA receives + * focus. + * + * @author Robert Futrell + * @version 1.0 + */ +public class JavaOutlineTree extends AbstractSourceTree { + + private DefaultTreeModel model; + private RSyntaxTextArea textArea; + private JavaParser parser; + private Listener listener; + + + /** + * Constructor. The tree created will not have its elements sorted + * alphabetically. + */ + public JavaOutlineTree() { + this(false); + } + + + /** + * Constructor. + * + * @param sorted Whether the tree should sort its elements alphabetically. + * Note that outline trees will likely group nodes by type before + * sorting (i.e. methods will be sorted in one group, fields in + * another group, etc.). + */ + public JavaOutlineTree(boolean sorted) { + setSorted(sorted); + setBorder(BorderFactory.createEmptyBorder(0,8,0,8)); + setRootVisible(false); + setCellRenderer(new AstTreeCellRenderer()); + model = new DefaultTreeModel(new DefaultMutableTreeNode("Nothing")); + setModel(model); + listener = new Listener(); + addTreeSelectionListener(listener); + } + + + /** + * Refreshes this tree. + * + * @param cu The parsed compilation unit. If this is null + * then the tree is cleared. + */ + private void update(CompilationUnit cu) { + + JavaTreeNode root = new JavaTreeNode("Remove me!", + IconFactory.SOURCE_FILE_ICON); + root.setSortable(false); + if (cu==null) { + model.setRoot(root); + return; + } + + Package pkg = cu.getPackage(); + if (pkg!=null) { + String iconName = IconFactory.PACKAGE_ICON; + root.add(new JavaTreeNode(pkg, iconName, false)); + } + + if (!getShowMajorElementsOnly()) { + JavaTreeNode importNode = new JavaTreeNode("Imports", + IconFactory.IMPORT_ROOT_ICON); + Iterator i = cu.getImportIterator(); + while (i.hasNext()) { + ImportDeclaration idec = i.next(); + JavaTreeNode iNode = new JavaTreeNode(idec, + IconFactory.IMPORT_ICON); + importNode.add(iNode); + } + root.add(importNode); + } + + Iterator i = cu.getTypeDeclarationIterator(); + while (i.hasNext()) { + TypeDeclaration td = i.next(); + TypeDeclarationTreeNode dmtn = createTypeDeclarationNode(td); + root.add(dmtn); + } + + model.setRoot(root); + root.setSorted(isSorted()); + refresh(); + + } + + + /** + * Refreshes listeners on the text area when its syntax style changes. + */ + private void checkForJavaParsing() { + + // Remove possible listener on old Java parser (in case they're just + // changing syntax style AWAY from Java) + if (parser!=null) { + parser.removePropertyChangeListener( + JavaParser.PROPERTY_COMPILATION_UNIT, listener); + parser = null; + } + + // Get the Java language support (shared by all RSTA instances editing + // Java that were registered with the LanguageSupportFactory). + LanguageSupportFactory lsf = LanguageSupportFactory.get(); + LanguageSupport support = lsf.getSupportFor(JavaTokenRegistration.SYNTAX_STYLE); + JavaLanguageSupport jls = (JavaLanguageSupport)support; + + // Listen for re-parsing of the editor, and update the tree accordingly + parser = jls.getParser(textArea); + if (parser!=null) { // Should always be true + parser.addPropertyChangeListener( + JavaParser.PROPERTY_COMPILATION_UNIT, listener); + // Populate with any already-existing CompilationUnit + CompilationUnit cu = parser.getCompilationUnit(); + update(cu); + } + else { + update((CompilationUnit)null); // Clear the tree + } + + } + + + private MemberTreeNode createMemberNode(Member member) { + + MemberTreeNode node = null; + if (member instanceof CodeBlock) { + node = new MemberTreeNode((CodeBlock)member); + } + else if (member instanceof Field) { + node = new MemberTreeNode((Field)member); + } + else { + node = new MemberTreeNode((Method)member); + } + + CodeBlock body = null; + if (member instanceof CodeBlock) { + body = (CodeBlock)member; + } + else if (member instanceof Method) { + body = ((Method)member).getBody(); + } + + if (body!=null && !getShowMajorElementsOnly()) { + for (int i=0; i i = ncd.getMemberIterator(); + while (i.hasNext()) { + dmtn.add(createMemberNode(i.next())); + } + } + + else if (td instanceof NormalInterfaceDeclaration) { + NormalInterfaceDeclaration nid = (NormalInterfaceDeclaration)td; + for (int j=0; j i = nid.getMemberIterator(); + while (i.hasNext()) { + dmtn.add(createMemberNode(i.next())); + } + } + + return dmtn; + + } + + + /** + * {@inheritDoc} + */ + @Override + public void expandInitialNodes() { + + // First, collapse all rows. + int j=0; + while (jgetText(false), so + * we look nice with ToolTipTrees. + * + * @return A string representation of this tree node. + */ + @Override + public String toString() { + return getText(false); + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/tree/LocalVarTreeNode.java b/src/main/java/org/fife/rsta/ac/bsh/tree/LocalVarTreeNode.java new file mode 100644 index 00000000..d739b461 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/tree/LocalVarTreeNode.java @@ -0,0 +1,53 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.tree; + +import org.fife.rsta.ac.bsh.IconFactory; +import org.fife.rsta.ac.bsh.rjc.ast.LocalVariable; +import org.fife.ui.autocomplete.Util; + + +/** + * Tree node for a local variable. + * + * @author Robert Futrell + * @version 1.0 + */ +class LocalVarTreeNode extends JavaTreeNode { + + private String text; + + + public LocalVarTreeNode(LocalVariable var) { + + super(var); + setIcon(IconFactory.get().getIcon(IconFactory.LOCAL_VARIABLE_ICON)); + setSortPriority(PRIORITY_LOCAL_VAR); + + StringBuilder sb = new StringBuilder(); + sb.append(""); + sb.append(var.getName()); + sb.append(" : "); + sb.append(""); + MemberTreeNode.appendType(var.getType(), sb); + text = sb.toString(); + } + + + @Override + public String getText(boolean selected) { + // Strip out HTML tags + return selected ? Util.stripHtml(text). + replaceAll("<", "<").replaceAll(">", ">") : text; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/tree/MemberTreeNode.java b/src/main/java/org/fife/rsta/ac/bsh/tree/MemberTreeNode.java new file mode 100644 index 00000000..f65d8bf6 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/tree/MemberTreeNode.java @@ -0,0 +1,195 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.tree; + +import javax.swing.Icon; + +import org.fife.rsta.ac.bsh.DecoratableIcon; +import org.fife.rsta.ac.bsh.IconFactory; +import org.fife.rsta.ac.bsh.rjc.ast.CodeBlock; +import org.fife.rsta.ac.bsh.rjc.ast.Field; +import org.fife.rsta.ac.bsh.rjc.ast.FormalParameter; +import org.fife.rsta.ac.bsh.rjc.ast.Method; +import org.fife.rsta.ac.bsh.rjc.lang.Modifiers; +import org.fife.rsta.ac.bsh.rjc.lang.Type; +import org.fife.ui.autocomplete.Util; + + +/** + * Tree node for a field or method. + * + * @author Robert Futrell + * @version 1.0 + */ +class MemberTreeNode extends JavaTreeNode { + + private String text; + + + public MemberTreeNode(CodeBlock cb) { + super(cb); + text = "" + cb.getName(); + IconFactory fact = IconFactory.get(); + Icon base = fact.getIcon(IconFactory.METHOD_PRIVATE_ICON); + DecoratableIcon di = new DecoratableIcon(base); + int priority = PRIORITY_METHOD; + if (cb.isStatic()) { + di.addDecorationIcon(fact.getIcon(IconFactory.STATIC_ICON)); + priority += PRIORITY_BOOST_STATIC; + } + setIcon(di); + setSortPriority(priority); + } + + + public MemberTreeNode(Field field) { + + super(field); + + Modifiers mods = field.getModifiers(); + String icon = null; + + if (mods==null) { + icon = IconFactory.FIELD_DEFAULT_ICON; + } + else if (mods.isPrivate()) { + icon = IconFactory.FIELD_PRIVATE_ICON; + } + else if (mods.isProtected()) { + icon = IconFactory.FIELD_PROTECTED_ICON; + } + else if (mods.isPublic()) { + icon = IconFactory.FIELD_PUBLIC_ICON; + } + else { + icon = IconFactory.FIELD_DEFAULT_ICON; + } + + StringBuilder sb = new StringBuilder(); + sb.append(""); + sb.append(field.getName()); + sb.append(" : "); + sb.append(""); + + appendType(field.getType(), sb); + text = sb.toString(); + int priority = PRIORITY_FIELD; + + IconFactory fact = IconFactory.get(); + Icon base = fact.getIcon(icon); + DecoratableIcon di = new DecoratableIcon(base); + di.setDeprecated(field.isDeprecated()); + if (mods!=null) { + if (mods.isStatic()) { + di.addDecorationIcon(fact.getIcon(IconFactory.STATIC_ICON)); + priority += PRIORITY_BOOST_STATIC; + } + if (mods.isFinal()) { + di.addDecorationIcon(fact.getIcon(IconFactory.FINAL_ICON)); + } + } + setIcon(di); + + setSortPriority(priority); + + } + + + public MemberTreeNode(Method method) { + + super(method); + + String icon = null; + int priority = PRIORITY_METHOD; + + Modifiers mods = method.getModifiers(); + if (mods==null) { + icon = IconFactory.METHOD_DEFAULT_ICON; + } + else if (mods.isPrivate()) { + icon = IconFactory.METHOD_PRIVATE_ICON; + } + else if (mods.isProtected()) { + icon = IconFactory.METHOD_PROTECTED_ICON; + } + else if (mods.isPublic()) { + icon = IconFactory.METHOD_PUBLIC_ICON; + } + else { + icon = IconFactory.METHOD_DEFAULT_ICON; + } + StringBuilder sb = new StringBuilder(); + sb.append(""); + sb.append(method.getName()); + sb.append('('); + int paramCount = method.getParameterCount(); + for (int i=0; i"); + appendType(method.getType(), sb); + } + + text = sb.toString(); + + IconFactory fact = IconFactory.get(); + Icon base = fact.getIcon(icon); + DecoratableIcon di = new DecoratableIcon(base); + di.setDeprecated(method.isDeprecated()); + if (mods!=null) { + if (mods.isAbstract()) { + di.addDecorationIcon(fact.getIcon(IconFactory.ABSTRACT_ICON)); + } + if (method.isConstructor()) { + di.addDecorationIcon(fact.getIcon(IconFactory.CONSTRUCTOR_ICON)); + priority = PRIORITY_CONSTRUCTOR; // Overrides previous value + } + if (mods.isStatic()) { + di.addDecorationIcon(fact.getIcon(IconFactory.STATIC_ICON)); + priority += PRIORITY_BOOST_STATIC; + } + if (mods.isFinal()) { + di.addDecorationIcon(fact.getIcon(IconFactory.FINAL_ICON)); + } + } + setIcon(di); + + setSortPriority(priority); + + } + + + static void appendType(Type type, StringBuilder sb) { + if (type!=null) { + String t = type.toString(); + t = t.replaceAll("<", "<"); + t = t.replaceAll(">", ">"); + sb.append(t); + } + } + + + @Override + public String getText(boolean selected) { + // Strip out HTML tags + return selected ? Util.stripHtml(text). + replaceAll("<", "<").replaceAll(">", ">") : text; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/tree/TypeDeclarationTreeNode.java b/src/main/java/org/fife/rsta/ac/bsh/tree/TypeDeclarationTreeNode.java new file mode 100644 index 00000000..bf5b7b1c --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/bsh/tree/TypeDeclarationTreeNode.java @@ -0,0 +1,130 @@ +/* + * 03/21/2010 + * + * Copyright (C) 2010 Robert Futrell + * robert_futrell at users.sourceforge.net + * http://fifesoft.com/rsyntaxtextarea + * + * This library is distributed under a modified BSD license. See the included + * RSTALanguageSupport.License.txt file for details. + */ +package org.fife.rsta.ac.bsh.tree; + +import javax.swing.Icon; + +import org.fife.rsta.ac.bsh.DecoratableIcon; +import org.fife.rsta.ac.bsh.IconFactory; +import org.fife.rsta.ac.bsh.rjc.ast.EnumDeclaration; +import org.fife.rsta.ac.bsh.rjc.ast.NormalClassDeclaration; +import org.fife.rsta.ac.bsh.rjc.ast.NormalInterfaceDeclaration; +import org.fife.rsta.ac.bsh.rjc.ast.TypeDeclaration; +import org.fife.rsta.ac.bsh.rjc.lang.Modifiers; + + +/** + * Tree node for type declarations. + * + * @author Robert Futrell + * @version 1.0 + */ +class TypeDeclarationTreeNode extends JavaTreeNode { + + + public TypeDeclarationTreeNode(TypeDeclaration typeDec) { + + super(typeDec); + //System.out.println("... " + typeDec); + String iconName = null; + int priority = PRIORITY_TYPE; + + if (typeDec instanceof NormalClassDeclaration) { + NormalClassDeclaration ncd = (NormalClassDeclaration)typeDec; + if (ncd.getModifiers()!=null) { + if (ncd.getModifiers().isPublic()) { + iconName = IconFactory.CLASS_ICON; + } + else if (ncd.getModifiers().isProtected()) { + iconName = IconFactory.INNER_CLASS_PROTECTED_ICON; + } + else if (ncd.getModifiers().isPrivate()) { + iconName = IconFactory.INNER_CLASS_PRIVATE_ICON; + } + else { + iconName = IconFactory.INNER_CLASS_DEFAULT_ICON; + } + } + else { +//System.out.println("... " + value); + iconName = IconFactory.DEFAULT_CLASS_ICON; + } + } + else if (typeDec instanceof NormalInterfaceDeclaration) { + NormalInterfaceDeclaration nid = (NormalInterfaceDeclaration)typeDec; + if (nid.getModifiers()!=null && nid.getModifiers().isPublic()) { + iconName = IconFactory.INTERFACE_ICON; + } + else { + iconName = IconFactory.DEFAULT_INTERFACE_ICON; + } + } + else if (typeDec instanceof EnumDeclaration) { + EnumDeclaration ed = (EnumDeclaration)typeDec; + if (ed.getModifiers()!=null) { + if (ed.getModifiers().isPublic()) { + iconName = IconFactory.ENUM_ICON; + } + else if (ed.getModifiers().isProtected()) { + iconName = IconFactory.ENUM_PROTECTED_ICON;; + } + else if (ed.getModifiers().isPrivate()) { + iconName = IconFactory.ENUM_PRIVATE_ICON; + } + else { + iconName = IconFactory.ENUM_DEFAULT_ICON; + } + } + else { + //System.out.println("... " + value); + iconName = IconFactory.ENUM_DEFAULT_ICON; + } + } + + IconFactory fact = IconFactory.get(); + Icon mainIcon = fact.getIcon(iconName); + + if (mainIcon==null) { // Unknown type ??? + System.out.println("*** " + typeDec); + } + else { + DecoratableIcon di = new DecoratableIcon(mainIcon); + di.setDeprecated(typeDec.isDeprecated()); + Modifiers mods = typeDec.getModifiers(); + if (mods!=null) { + if (mods.isAbstract()) { + di.addDecorationIcon(fact.getIcon(IconFactory.ABSTRACT_ICON)); + } + else if (mods.isFinal()) { + di.addDecorationIcon(fact.getIcon(IconFactory.FINAL_ICON)); + } + if (mods.isStatic()) { + di.addDecorationIcon(fact.getIcon(IconFactory.STATIC_ICON)); + priority = PRIORITY_BOOST_STATIC; + } + } + setIcon(di); + } + + setSortPriority(priority); + + } + + + @Override + public String getText(boolean selected) { + TypeDeclaration typeDec = (TypeDeclaration)getUserObject(); + //System.out.println("... " + typeDec); + return typeDec!=null ? typeDec.getName() : null; + } + + +} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/c/CLanguageRegistration.java b/src/main/java/org/fife/rsta/ac/c/CLanguageRegistration.java new file mode 100644 index 00000000..97d7581e --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/c/CLanguageRegistration.java @@ -0,0 +1,27 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.fife.rsta.ac.c; + +import org.fife.rsta.ac.LanguageSupportRegistration; +import org.fife.ui.rsyntaxtextarea.modes.CTokenRegistration; + +/** + * + * @author matta + */ +public class CLanguageRegistration implements LanguageSupportRegistration { + + @Override + public String getLanguage() { + return CTokenRegistration.SYNTAX_STYLE; + } + + @Override + public String getLanguageSupportType() { + return CLanguageSupport.class.getName(); + } + +} diff --git a/src/main/java/org/fife/rsta/ac/c/CLanguageSupport.java b/src/main/java/org/fife/rsta/ac/c/CLanguageSupport.java index 9754ec40..54e34de7 100644 --- a/src/main/java/org/fife/rsta/ac/c/CLanguageSupport.java +++ b/src/main/java/org/fife/rsta/ac/c/CLanguageSupport.java @@ -38,8 +38,7 @@ public CLanguageSupport() { setParameterAssistanceEnabled(true); setShowDescWindow(true); } - - + /** * {@inheritDoc} */ diff --git a/src/main/java/org/fife/rsta/ac/css/CssLanguageRegistration.java b/src/main/java/org/fife/rsta/ac/css/CssLanguageRegistration.java new file mode 100644 index 00000000..fc6ac6e4 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/css/CssLanguageRegistration.java @@ -0,0 +1,27 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.fife.rsta.ac.css; + +import org.fife.rsta.ac.LanguageSupportRegistration; +import org.fife.ui.rsyntaxtextarea.modes.CSSTokenRegistration; + +/** + * + * @author matta + */ +public class CssLanguageRegistration implements LanguageSupportRegistration { + + @Override + public String getLanguage() { + return CSSTokenRegistration.SYNTAX_STYLE; + } + + @Override + public String getLanguageSupportType() { + return CssLanguageSupport.class.getName(); + } + +} diff --git a/src/main/java/org/fife/rsta/ac/css/CssLanguageSupport.java b/src/main/java/org/fife/rsta/ac/css/CssLanguageSupport.java index c14c9149..e2e72e56 100644 --- a/src/main/java/org/fife/rsta/ac/css/CssLanguageSupport.java +++ b/src/main/java/org/fife/rsta/ac/css/CssLanguageSupport.java @@ -41,7 +41,6 @@ public CssLanguageSupport() { //setShowDescWindow(true); } - @Override protected ListCellRenderer createDefaultCompletionCellRenderer() { return new CssCellRenderer(); diff --git a/src/main/java/org/fife/rsta/ac/demo/DemoRootPane.java b/src/main/java/org/fife/rsta/ac/demo/DemoRootPane.java index 4bad970b..650813ae 100644 --- a/src/main/java/org/fife/rsta/ac/demo/DemoRootPane.java +++ b/src/main/java/org/fife/rsta/ac/demo/DemoRootPane.java @@ -33,6 +33,18 @@ import org.fife.ui.rsyntaxtextarea.ErrorStrip; import org.fife.ui.rsyntaxtextarea.SyntaxConstants; import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; +import org.fife.ui.rsyntaxtextarea.modes.CSSTokenRegistration; +import org.fife.ui.rsyntaxtextarea.modes.CTokenRegistration; +import org.fife.ui.rsyntaxtextarea.modes.GroovyTokenRegistration; +import org.fife.ui.rsyntaxtextarea.modes.HTMLTokenRegistration; +import org.fife.ui.rsyntaxtextarea.modes.JSPTokenRegistration; +import org.fife.ui.rsyntaxtextarea.modes.JavaScriptTokenRegistration; +import org.fife.ui.rsyntaxtextarea.modes.JavaTokenRegistration; +import org.fife.ui.rsyntaxtextarea.modes.LessTokenRegistration; +import org.fife.ui.rsyntaxtextarea.modes.PHPTokenRegistration; +import org.fife.ui.rsyntaxtextarea.modes.PerlTokenRegistration; +import org.fife.ui.rsyntaxtextarea.modes.UnixShellTokenRegistration; +import org.fife.ui.rsyntaxtextarea.modes.XMLTokenRegistration; import org.fife.ui.rtextarea.RTextScrollPane; @@ -55,7 +67,7 @@ class DemoRootPane extends JRootPane implements HyperlinkListener, public DemoRootPane() { LanguageSupportFactory lsf = LanguageSupportFactory.get(); - LanguageSupport support = lsf.getSupportFor(SYNTAX_STYLE_JAVA); + LanguageSupport support = lsf.getSupportFor(JavaTokenRegistration.SYNTAX_STYLE); JavaLanguageSupport jls = (JavaLanguageSupport)support; // TODO: This API will change! It will be easier to do per-editor // changes to the build path. @@ -71,7 +83,7 @@ public DemoRootPane() { treeSP = new JScrollPane(dummy); textArea = createTextArea(); - setText("CExample.txt", SYNTAX_STYLE_C); + setText("CExample.txt", CTokenRegistration.SYNTAX_STYLE); scrollPane = new RTextScrollPane(textArea, true); scrollPane.setIconRowHeaderEnabled(true); scrollPane.getGutter().setBookmarkingEnabled(true); @@ -116,18 +128,18 @@ private JMenuBar createMenuBar() { menu = new JMenu("Language"); ButtonGroup bg = new ButtonGroup(); - addItem(new StyleAction(this, "C", "CExample.txt", SYNTAX_STYLE_C), bg, menu); - addItem(new StyleAction(this, "CSS", "CssExample.txt", SYNTAX_STYLE_CSS), bg, menu); - addItem(new StyleAction(this, "Groovy", "GroovyExample.txt", SYNTAX_STYLE_GROOVY), bg, menu); - addItem(new StyleAction(this, "Java", "JavaExample.txt", SYNTAX_STYLE_JAVA), bg, menu); - addItem(new StyleAction(this, "JavaScript", "JSExample.txt", SYNTAX_STYLE_JAVASCRIPT), bg, menu); - addItem(new StyleAction(this, "JSP", "JspExample.txt", SYNTAX_STYLE_JSP), bg, menu); - addItem(new StyleAction(this, "Less", "LessExample.txt", SYNTAX_STYLE_LESS), bg, menu); - addItem(new StyleAction(this, "Perl", "PerlExample.txt", SYNTAX_STYLE_PERL), bg, menu); - addItem(new StyleAction(this, "HTML", "HtmlExample.txt", SYNTAX_STYLE_HTML), bg, menu); - addItem(new StyleAction(this, "PHP", "PhpExample.txt", SYNTAX_STYLE_PHP), bg, menu); - addItem(new StyleAction(this, "sh", "ShellExample.txt", SYNTAX_STYLE_UNIX_SHELL), bg, menu); - addItem(new StyleAction(this, "XML", "XMLExample.txt", SYNTAX_STYLE_XML), bg, menu); + addItem(new StyleAction(this, "C", "CExample.txt", CTokenRegistration.SYNTAX_STYLE), bg, menu); + addItem(new StyleAction(this, "CSS", "CssExample.txt", CSSTokenRegistration.SYNTAX_STYLE), bg, menu); + addItem(new StyleAction(this, "Groovy", "GroovyExample.txt", GroovyTokenRegistration.SYNTAX_STYLE), bg, menu); + addItem(new StyleAction(this, "Java", "JavaExample.txt", JavaTokenRegistration.SYNTAX_STYLE), bg, menu); + addItem(new StyleAction(this, "JavaScript", "JSExample.txt", JavaScriptTokenRegistration.SYNTAX_STYLE), bg, menu); + addItem(new StyleAction(this, "JSP", "JspExample.txt", JSPTokenRegistration.SYNTAX_STYLE), bg, menu); + addItem(new StyleAction(this, "Less", "LessExample.txt", LessTokenRegistration.SYNTAX_STYLE), bg, menu); + addItem(new StyleAction(this, "Perl", "PerlExample.txt", PerlTokenRegistration.SYNTAX_STYLE), bg, menu); + addItem(new StyleAction(this, "HTML", "HtmlExample.txt", HTMLTokenRegistration.SYNTAX_STYLE), bg, menu); + addItem(new StyleAction(this, "PHP", "PhpExample.txt", PHPTokenRegistration.SYNTAX_STYLE), bg, menu); + addItem(new StyleAction(this, "sh", "ShellExample.txt", UnixShellTokenRegistration.SYNTAX_STYLE), bg, menu); + addItem(new StyleAction(this, "XML", "XMLExample.txt", XMLTokenRegistration.SYNTAX_STYLE), bg, menu); menu.getItem(0).setSelected(true); mb.add(menu); @@ -238,13 +250,13 @@ private void refreshSourceTree() { } String language = textArea.getSyntaxEditingStyle(); - if (SyntaxConstants.SYNTAX_STYLE_JAVA.equals(language)) { + if (JavaTokenRegistration.SYNTAX_STYLE.equals(language)) { tree = new JavaOutlineTree(); } - else if (SyntaxConstants.SYNTAX_STYLE_JAVASCRIPT.equals(language)) { + else if (JavaScriptTokenRegistration.SYNTAX_STYLE.equals(language)) { tree = new JavaScriptOutlineTree(); } - else if (SyntaxConstants.SYNTAX_STYLE_XML.equals(language)) { + else if (XMLTokenRegistration.SYNTAX_STYLE.equals(language)) { tree = new XmlOutlineTree(); } else { diff --git a/src/main/java/org/fife/rsta/ac/groovy/GroovyLanguageRegistration.java b/src/main/java/org/fife/rsta/ac/groovy/GroovyLanguageRegistration.java new file mode 100644 index 00000000..dccbf8a5 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/groovy/GroovyLanguageRegistration.java @@ -0,0 +1,27 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.fife.rsta.ac.groovy; + +import org.fife.rsta.ac.LanguageSupportRegistration; +import org.fife.ui.rsyntaxtextarea.modes.GroovyTokenRegistration; + +/** + * + * @author matta + */ +public class GroovyLanguageRegistration implements LanguageSupportRegistration { + + @Override + public String getLanguage() { + return GroovyTokenRegistration.SYNTAX_STYLE; + } + + @Override + public String getLanguageSupportType() { + return GroovyLanguageSupport.class.getName(); + } + +} diff --git a/src/main/java/org/fife/rsta/ac/groovy/GroovyLanguageSupport.java b/src/main/java/org/fife/rsta/ac/groovy/GroovyLanguageSupport.java index a44d8936..f337e399 100644 --- a/src/main/java/org/fife/rsta/ac/groovy/GroovyLanguageSupport.java +++ b/src/main/java/org/fife/rsta/ac/groovy/GroovyLanguageSupport.java @@ -39,7 +39,6 @@ public GroovyLanguageSupport() { setShowDescWindow(true); } - // /** // * {@inheritDoc} // */ diff --git a/src/main/java/org/fife/rsta/ac/html/HtmlLanguageRegistration.java b/src/main/java/org/fife/rsta/ac/html/HtmlLanguageRegistration.java new file mode 100644 index 00000000..a20bb5d8 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/html/HtmlLanguageRegistration.java @@ -0,0 +1,27 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.fife.rsta.ac.html; + +import org.fife.rsta.ac.LanguageSupportRegistration; +import org.fife.ui.rsyntaxtextarea.modes.HTMLTokenRegistration; + +/** + * + * @author matta + */ +public class HtmlLanguageRegistration implements LanguageSupportRegistration { + + @Override + public String getLanguage() { + return HTMLTokenRegistration.SYNTAX_STYLE; + } + + @Override + public String getLanguageSupportType() { + return HtmlLanguageSupport.class.getName(); + } + +} diff --git a/src/main/java/org/fife/rsta/ac/html/HtmlLanguageSupport.java b/src/main/java/org/fife/rsta/ac/html/HtmlLanguageSupport.java index edfe023c..7cc52852 100644 --- a/src/main/java/org/fife/rsta/ac/html/HtmlLanguageSupport.java +++ b/src/main/java/org/fife/rsta/ac/html/HtmlLanguageSupport.java @@ -56,7 +56,6 @@ public HtmlLanguageSupport() { setShowDescWindow(true); } - /** * {@inheritDoc} */ diff --git a/src/main/java/org/fife/rsta/ac/java/JavaLanguageRegistration.java b/src/main/java/org/fife/rsta/ac/java/JavaLanguageRegistration.java new file mode 100644 index 00000000..2254203d --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/java/JavaLanguageRegistration.java @@ -0,0 +1,27 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.fife.rsta.ac.java; + +import org.fife.rsta.ac.LanguageSupportRegistration; +import org.fife.ui.rsyntaxtextarea.modes.JavaTokenRegistration; + +/** + * + * @author matta + */ +public class JavaLanguageRegistration implements LanguageSupportRegistration { + + @Override + public String getLanguage() { + return JavaTokenRegistration.SYNTAX_STYLE; + } + + @Override + public String getLanguageSupportType() { + return JavaLanguageSupport.class.getName(); + } + +} diff --git a/src/main/java/org/fife/rsta/ac/java/JavadocUrlHandler.java b/src/main/java/org/fife/rsta/ac/java/JavadocUrlHandler.java index 7cb76662..3629de6a 100644 --- a/src/main/java/org/fife/rsta/ac/java/JavadocUrlHandler.java +++ b/src/main/java/org/fife/rsta/ac/java/JavadocUrlHandler.java @@ -25,7 +25,7 @@ import org.fife.ui.autocomplete.DescWindowCallback; import org.fife.ui.autocomplete.ExternalURLHandler; import org.fife.ui.autocomplete.Util; -import org.fife.ui.rsyntaxtextarea.SyntaxConstants; +import org.fife.ui.rsyntaxtextarea.modes.JavaTokenRegistration; /** @@ -65,7 +65,7 @@ private String doBackups(String pkg, int backupCount) { */ private JavaLanguageSupport getJavaLanguageSupport() { return (JavaLanguageSupport)LanguageSupportFactory.get(). - getSupportFor(SyntaxConstants.SYNTAX_STYLE_JAVA); + getSupportFor(JavaTokenRegistration.SYNTAX_STYLE); } diff --git a/src/main/java/org/fife/rsta/ac/java/SourceParamChoicesProvider.java b/src/main/java/org/fife/rsta/ac/java/SourceParamChoicesProvider.java index ff1876e8..60007ae3 100644 --- a/src/main/java/org/fife/rsta/ac/java/SourceParamChoicesProvider.java +++ b/src/main/java/org/fife/rsta/ac/java/SourceParamChoicesProvider.java @@ -39,7 +39,7 @@ import org.fife.ui.autocomplete.ParameterChoicesProvider; import org.fife.ui.autocomplete.ParameterizedCompletion; import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; -import org.fife.ui.rsyntaxtextarea.SyntaxConstants; +import org.fife.ui.rsyntaxtextarea.modes.JavaTokenRegistration; /** @@ -165,8 +165,7 @@ public List getParameterChoices(JTextComponent tc, // Get the language support for Java LanguageSupportFactory lsf = LanguageSupportFactory.get(); - LanguageSupport support = lsf.getSupportFor(SyntaxConstants. - SYNTAX_STYLE_JAVA); + LanguageSupport support = lsf.getSupportFor(JavaTokenRegistration.SYNTAX_STYLE); JavaLanguageSupport jls = (JavaLanguageSupport)support; JarManager jm = jls.getJarManager(); diff --git a/src/main/java/org/fife/rsta/ac/java/tree/JavaOutlineTree.java b/src/main/java/org/fife/rsta/ac/java/tree/JavaOutlineTree.java index b07d4349..1d40ea47 100644 --- a/src/main/java/org/fife/rsta/ac/java/tree/JavaOutlineTree.java +++ b/src/main/java/org/fife/rsta/ac/java/tree/JavaOutlineTree.java @@ -42,6 +42,7 @@ import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; import org.fife.ui.rsyntaxtextarea.RSyntaxUtilities; import org.fife.ui.rsyntaxtextarea.SyntaxConstants; +import org.fife.ui.rsyntaxtextarea.modes.JavaTokenRegistration; /** @@ -163,8 +164,7 @@ private void checkForJavaParsing() { // Get the Java language support (shared by all RSTA instances editing // Java that were registered with the LanguageSupportFactory). LanguageSupportFactory lsf = LanguageSupportFactory.get(); - LanguageSupport support = lsf.getSupportFor(SyntaxConstants. - SYNTAX_STYLE_JAVA); + LanguageSupport support = lsf.getSupportFor(JavaTokenRegistration.SYNTAX_STYLE); JavaLanguageSupport jls = (JavaLanguageSupport)support; // Listen for re-parsing of the editor, and update the tree accordingly diff --git a/src/main/java/org/fife/rsta/ac/js/JavaScriptLanguageRegistration.java b/src/main/java/org/fife/rsta/ac/js/JavaScriptLanguageRegistration.java new file mode 100644 index 00000000..852629ad --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/js/JavaScriptLanguageRegistration.java @@ -0,0 +1,27 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.fife.rsta.ac.js; + +import org.fife.rsta.ac.LanguageSupportRegistration; +import org.fife.ui.rsyntaxtextarea.modes.JavaScriptTokenRegistration; + +/** + * + * @author matta + */ +public class JavaScriptLanguageRegistration implements LanguageSupportRegistration { + + @Override + public String getLanguage() { + return JavaScriptTokenRegistration.SYNTAX_STYLE; + } + + @Override + public String getLanguageSupportType() { + return JavaScriptLanguageSupport.class.getName(); + } + +} diff --git a/src/main/java/org/fife/rsta/ac/js/JavaScriptLanguageSupport.java b/src/main/java/org/fife/rsta/ac/js/JavaScriptLanguageSupport.java index 5b2d3233..2aede80c 100644 --- a/src/main/java/org/fife/rsta/ac/js/JavaScriptLanguageSupport.java +++ b/src/main/java/org/fife/rsta/ac/js/JavaScriptLanguageSupport.java @@ -100,7 +100,6 @@ public JavaScriptLanguageSupport() { setLanguageVersion(Integer.MIN_VALUE); // Take Rhino's default } - /** * Creates a jar manager instance for used in JS language support. * diff --git a/src/main/java/org/fife/rsta/ac/js/tree/JavaScriptOutlineTree.java b/src/main/java/org/fife/rsta/ac/js/tree/JavaScriptOutlineTree.java index f621a902..11cc883a 100644 --- a/src/main/java/org/fife/rsta/ac/js/tree/JavaScriptOutlineTree.java +++ b/src/main/java/org/fife/rsta/ac/js/tree/JavaScriptOutlineTree.java @@ -28,7 +28,7 @@ import org.fife.ui.rsyntaxtextarea.DocumentRange; import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; import org.fife.ui.rsyntaxtextarea.RSyntaxUtilities; -import org.fife.ui.rsyntaxtextarea.SyntaxConstants; +import org.fife.ui.rsyntaxtextarea.modes.JavaScriptTokenRegistration; import org.mozilla.javascript.ast.AstRoot; @@ -102,8 +102,7 @@ private void checkForJavaScriptParsing() { // Get the Java language support (shared by all RSTA instances editing // Java that were registered with the LanguageSupportFactory). LanguageSupportFactory lsf = LanguageSupportFactory.get(); - LanguageSupport support = lsf.getSupportFor(SyntaxConstants. - SYNTAX_STYLE_JAVASCRIPT); + LanguageSupport support = lsf.getSupportFor(JavaScriptTokenRegistration.SYNTAX_STYLE); JavaScriptLanguageSupport jls = (JavaScriptLanguageSupport)support; // Listen for re-parsing of the editor, and update the tree accordingly diff --git a/src/main/java/org/fife/rsta/ac/jsp/JspLanguageRegistration.java b/src/main/java/org/fife/rsta/ac/jsp/JspLanguageRegistration.java new file mode 100644 index 00000000..609b0132 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/jsp/JspLanguageRegistration.java @@ -0,0 +1,27 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.fife.rsta.ac.jsp; + +import org.fife.rsta.ac.LanguageSupportRegistration; +import org.fife.ui.rsyntaxtextarea.modes.JSPTokenRegistration; + +/** + * + * @author matta + */ +public class JspLanguageRegistration implements LanguageSupportRegistration { + + @Override + public String getLanguage() { + return JSPTokenRegistration.SYNTAX_STYLE; + } + + @Override + public String getLanguageSupportType() { + return JspLanguageSupport.class.getName(); + } + +} diff --git a/src/main/java/org/fife/rsta/ac/jsp/JspLanguageSupport.java b/src/main/java/org/fife/rsta/ac/jsp/JspLanguageSupport.java index 3fa6e840..437c904c 100644 --- a/src/main/java/org/fife/rsta/ac/jsp/JspLanguageSupport.java +++ b/src/main/java/org/fife/rsta/ac/jsp/JspLanguageSupport.java @@ -5,7 +5,7 @@ * robert_futrell at users.sourceforge.net * http://fifesoft.com/rsyntaxtextarea * - * This library is distributed under a modified BSD license. See the included + * This library is distributed under a modified BSD license. See the included * RSTALanguageSupport.License.txt file for details. */ package org.fife.rsta.ac.jsp; @@ -57,7 +57,6 @@ public JspLanguageSupport() { tagsToClose = HtmlLanguageSupport.getTagsToClose(); } - /** * {@inheritDoc} */ diff --git a/src/main/java/org/fife/rsta/ac/less/LessLanguageRegistration.java b/src/main/java/org/fife/rsta/ac/less/LessLanguageRegistration.java new file mode 100644 index 00000000..8ec43155 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/less/LessLanguageRegistration.java @@ -0,0 +1,27 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.fife.rsta.ac.less; + +import org.fife.rsta.ac.LanguageSupportRegistration; +import org.fife.ui.rsyntaxtextarea.modes.LessTokenRegistration; + +/** + * + * @author matta + */ +public class LessLanguageRegistration implements LanguageSupportRegistration { + + @Override + public String getLanguage() { + return LessTokenRegistration.SYNTAX_STYLE; + } + + @Override + public String getLanguageSupportType() { + return LessLanguageSupport.class.getName(); + } + +} diff --git a/src/main/java/org/fife/rsta/ac/less/LessLanguageSupport.java b/src/main/java/org/fife/rsta/ac/less/LessLanguageSupport.java index d07e3cac..47866a3a 100644 --- a/src/main/java/org/fife/rsta/ac/less/LessLanguageSupport.java +++ b/src/main/java/org/fife/rsta/ac/less/LessLanguageSupport.java @@ -13,7 +13,6 @@ import org.fife.rsta.ac.css.CssCompletionProvider; import org.fife.rsta.ac.css.CssLanguageSupport; - /** * Language support for Less. * @@ -22,24 +21,21 @@ */ public class LessLanguageSupport extends CssLanguageSupport { - - /** - * Constructor. - */ - public LessLanguageSupport() { - setShowDescWindow(true); - } - - - /** - * Overridden to return a completion provider that understands Less. - * - * @return A completion provider to use for this language. - */ - @Override - protected CssCompletionProvider createProvider() { - return new LessCompletionProvider(); - } - - -} \ No newline at end of file + /** + * Constructor. + */ + public LessLanguageSupport() { + setShowDescWindow(true); + } + + /** + * Overridden to return a completion provider that understands Less. + * + * @return A completion provider to use for this language. + */ + @Override + protected CssCompletionProvider createProvider() { + return new LessCompletionProvider(); + } + +} diff --git a/src/main/java/org/fife/rsta/ac/perl/PerlLanguageRegistration.java b/src/main/java/org/fife/rsta/ac/perl/PerlLanguageRegistration.java new file mode 100644 index 00000000..0237b6c2 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/perl/PerlLanguageRegistration.java @@ -0,0 +1,27 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.fife.rsta.ac.perl; + +import org.fife.rsta.ac.LanguageSupportRegistration; +import org.fife.ui.rsyntaxtextarea.modes.PerlTokenRegistration; + +/** + * + * @author matta + */ +public class PerlLanguageRegistration implements LanguageSupportRegistration { + + @Override + public String getLanguage() { + return PerlTokenRegistration.SYNTAX_STYLE; + } + + @Override + public String getLanguageSupportType() { + return PerlLanguageSupport.class.getName(); + } + +} diff --git a/src/main/java/org/fife/rsta/ac/perl/PerlLanguageSupport.java b/src/main/java/org/fife/rsta/ac/perl/PerlLanguageSupport.java index 6076f4df..a41d6d25 100644 --- a/src/main/java/org/fife/rsta/ac/perl/PerlLanguageSupport.java +++ b/src/main/java/org/fife/rsta/ac/perl/PerlLanguageSupport.java @@ -15,7 +15,6 @@ import org.fife.rsta.ac.AbstractLanguageSupport; import org.fife.rsta.ac.IOUtil; -import org.fife.rsta.ac.perl.PerlCompletionProvider; import org.fife.ui.autocomplete.AutoCompletion; import org.fife.ui.autocomplete.CompletionCellRenderer; import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; @@ -101,7 +100,6 @@ public PerlLanguageSupport() { setShowDescWindow(true); } - /** * {@inheritDoc} */ diff --git a/src/main/java/org/fife/rsta/ac/php/PhpLanguageRegistration.java b/src/main/java/org/fife/rsta/ac/php/PhpLanguageRegistration.java new file mode 100644 index 00000000..599444a2 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/php/PhpLanguageRegistration.java @@ -0,0 +1,27 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.fife.rsta.ac.php; + +import org.fife.rsta.ac.LanguageSupportRegistration; +import org.fife.ui.rsyntaxtextarea.modes.PHPTokenRegistration; + +/** + * + * @author matta + */ +public class PhpLanguageRegistration implements LanguageSupportRegistration { + + @Override + public String getLanguage() { + return PHPTokenRegistration.SYNTAX_STYLE; + } + + @Override + public String getLanguageSupportType() { + return PhpLanguageSupport.class.getName(); + } + +} diff --git a/src/main/java/org/fife/rsta/ac/php/PhpLanguageSupport.java b/src/main/java/org/fife/rsta/ac/php/PhpLanguageSupport.java index 352d6ed3..f6516fe9 100644 --- a/src/main/java/org/fife/rsta/ac/php/PhpLanguageSupport.java +++ b/src/main/java/org/fife/rsta/ac/php/PhpLanguageSupport.java @@ -20,97 +20,90 @@ import org.fife.ui.autocomplete.AutoCompletion; import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; - /** - * Language support for PHP. Features currently include: + * Language support for PHP. Features currently include: * *

      - *
    • Code completion for PHP functions.
    • - *
    • Code completion for HTML5 tags and attributes.
    • - *
    • Automatic creation of closing tags for non-self-closing tags.
    • + *
    • Code completion for PHP functions.
    • + *
    • Code completion for HTML5 tags and attributes.
    • + *
    • Automatic creation of closing tags for non-self-closing tags.
    • *
    - * + * * @author Robert Futrell * @version 1.0 */ public class PhpLanguageSupport extends AbstractMarkupLanguageSupport { - /** - * The completion provider. This is shared amongst all PHP text areas. - */ - private PhpCompletionProvider provider; - - /** - * A cached set of tags that require closing tags. - */ - private static Set tagsToClose = new HashSet(); - - - /** - * Constructor. - */ - public PhpLanguageSupport() { - setAutoActivationEnabled(true); - setParameterAssistanceEnabled(true); - setShowDescWindow(true); - tagsToClose = HtmlLanguageSupport.getTagsToClose(); - } - - - /** - * {@inheritDoc} - */ - @Override - protected ListCellRenderer createDefaultCompletionCellRenderer() { - return new HtmlCellRenderer(); - } - - - /** - * Lazily creates the shared completion provider instance for PHP. - * - * @return The completion provider. - */ - private PhpCompletionProvider getProvider() { - if (provider==null) { - provider = new PhpCompletionProvider(); - } - return provider; - } - - - /** - * {@inheritDoc} - */ - public void install(RSyntaxTextArea textArea) { - - PhpCompletionProvider provider = getProvider(); - AutoCompletion ac = createAutoCompletion(provider); - ac.install(textArea); - installImpl(textArea, ac); - installKeyboardShortcuts(textArea); - - textArea.setToolTipSupplier(null); - - } - - - /** - * {@inheritDoc} - */ - @Override - protected boolean shouldAutoCloseTag(String tag) { - return tagsToClose.contains(tag.toLowerCase()); - } - - - /** - * {@inheritDoc} - */ - public void uninstall(RSyntaxTextArea textArea) { - uninstallImpl(textArea); - uninstallKeyboardShortcuts(textArea); - } - - -} \ No newline at end of file + /** + * The completion provider. This is shared amongst all PHP text areas. + */ + private PhpCompletionProvider provider; + + /** + * A cached set of tags that require closing tags. + */ + private static Set tagsToClose = new HashSet(); + + /** + * Constructor. + */ + public PhpLanguageSupport() { + setAutoActivationEnabled(true); + setParameterAssistanceEnabled(true); + setShowDescWindow(true); + tagsToClose = HtmlLanguageSupport.getTagsToClose(); + } + + + /** + * {@inheritDoc} + */ + @Override + protected ListCellRenderer createDefaultCompletionCellRenderer() { + return new HtmlCellRenderer(); + } + + /** + * Lazily creates the shared completion provider instance for PHP. + * + * @return The completion provider. + */ + private PhpCompletionProvider getProvider() { + if (provider == null) { + provider = new PhpCompletionProvider(); + } + return provider; + } + + /** + * {@inheritDoc} + */ + public void install(RSyntaxTextArea textArea) { + + PhpCompletionProvider provider = getProvider(); + AutoCompletion ac = createAutoCompletion(provider); + ac.install(textArea); + installImpl(textArea, ac); + installKeyboardShortcuts(textArea); + + textArea.setToolTipSupplier(null); + + } + + /** + * {@inheritDoc} + */ + @Override + protected boolean shouldAutoCloseTag(String tag) { + return tagsToClose.contains(tag.toLowerCase()); + } + + /** + * {@inheritDoc} + */ + public void uninstall(RSyntaxTextArea textArea) { + uninstallImpl(textArea); + uninstallKeyboardShortcuts(textArea); + } + +} diff --git a/src/main/java/org/fife/rsta/ac/sh/ShellLanguageRegistration.java b/src/main/java/org/fife/rsta/ac/sh/ShellLanguageRegistration.java new file mode 100644 index 00000000..dadc77e6 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/sh/ShellLanguageRegistration.java @@ -0,0 +1,27 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.fife.rsta.ac.sh; + +import org.fife.rsta.ac.LanguageSupportRegistration; +import org.fife.ui.rsyntaxtextarea.modes.UnixShellTokenRegistration; + +/** + * + * @author matta + */ +public class ShellLanguageRegistration implements LanguageSupportRegistration { + + @Override + public String getLanguage() { + return UnixShellTokenRegistration.SYNTAX_STYLE; + } + + @Override + public String getLanguageSupportType() { + return ShellLanguageSupport.class.getName(); + } + +} diff --git a/src/main/java/org/fife/rsta/ac/sh/ShellLanguageSupport.java b/src/main/java/org/fife/rsta/ac/sh/ShellLanguageSupport.java index a9aaed8a..44d0bc35 100644 --- a/src/main/java/org/fife/rsta/ac/sh/ShellLanguageSupport.java +++ b/src/main/java/org/fife/rsta/ac/sh/ShellLanguageSupport.java @@ -48,6 +48,7 @@ public ShellLanguageSupport() { } + /** * {@inheritDoc} */ diff --git a/src/main/java/org/fife/rsta/ac/xml/XmlLanguageRegistration.java b/src/main/java/org/fife/rsta/ac/xml/XmlLanguageRegistration.java new file mode 100644 index 00000000..c9a5a3a3 --- /dev/null +++ b/src/main/java/org/fife/rsta/ac/xml/XmlLanguageRegistration.java @@ -0,0 +1,27 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.fife.rsta.ac.xml; + +import org.fife.rsta.ac.LanguageSupportRegistration; +import org.fife.ui.rsyntaxtextarea.modes.XMLTokenRegistration; + +/** + * + * @author matta + */ +public class XmlLanguageRegistration implements LanguageSupportRegistration { + + @Override + public String getLanguage() { + return XMLTokenRegistration.SYNTAX_STYLE; + } + + @Override + public String getLanguageSupportType() { + return XmlLanguageSupport.class.getName(); + } + +} diff --git a/src/main/java/org/fife/rsta/ac/xml/XmlLanguageSupport.java b/src/main/java/org/fife/rsta/ac/xml/XmlLanguageSupport.java index 2880ea00..aaf6cc58 100644 --- a/src/main/java/org/fife/rsta/ac/xml/XmlLanguageSupport.java +++ b/src/main/java/org/fife/rsta/ac/xml/XmlLanguageSupport.java @@ -72,7 +72,6 @@ public XmlLanguageSupport() { setShowSyntaxErrors(true); } - /** * {@inheritDoc} */ diff --git a/src/main/java/org/fife/rsta/ac/xml/tree/XmlOutlineTree.java b/src/main/java/org/fife/rsta/ac/xml/tree/XmlOutlineTree.java index 709549b0..b9af05fc 100644 --- a/src/main/java/org/fife/rsta/ac/xml/tree/XmlOutlineTree.java +++ b/src/main/java/org/fife/rsta/ac/xml/tree/XmlOutlineTree.java @@ -26,7 +26,7 @@ import org.fife.ui.rsyntaxtextarea.DocumentRange; import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; import org.fife.ui.rsyntaxtextarea.RSyntaxUtilities; -import org.fife.ui.rsyntaxtextarea.SyntaxConstants; +import org.fife.ui.rsyntaxtextarea.modes.XMLTokenRegistration; /** @@ -99,8 +99,7 @@ private void checkForXmlParsing() { // Get the Java language support (shared by all RSTA instances editing // Java that were registered with the LanguageSupportFactory). LanguageSupportFactory lsf = LanguageSupportFactory.get(); - LanguageSupport support = lsf.getSupportFor(SyntaxConstants. - SYNTAX_STYLE_XML); + LanguageSupport support = lsf.getSupportFor(XMLTokenRegistration.SYNTAX_STYLE); XmlLanguageSupport xls = (XmlLanguageSupport)support; // Listen for re-parsing of the editor, and update the tree accordingly diff --git a/src/main/resources/META-INF/services/org.fife.rsta.ac.LanguageSupportRegistration b/src/main/resources/META-INF/services/org.fife.rsta.ac.LanguageSupportRegistration new file mode 100644 index 00000000..1f350290 --- /dev/null +++ b/src/main/resources/META-INF/services/org.fife.rsta.ac.LanguageSupportRegistration @@ -0,0 +1,13 @@ +org.fife.rsta.ac.css.CssLanguageRegistration +org.fife.rsta.ac.xml.XmlLanguageRegistration +org.fife.rsta.ac.groovy.GroovyLanguageRegistration +org.fife.rsta.ac.jsp.JspLanguageRegistration +org.fife.rsta.ac.less.LessLanguageRegistration +org.fife.rsta.ac.js.JavaScriptLanguageRegistration +org.fife.rsta.ac.bsh.JavaLanguageRegistration +org.fife.rsta.ac.c.CLanguageRegistration +org.fife.rsta.ac.html.HtmlLanguageRegistration +org.fife.rsta.ac.php.PhpLanguageRegistration +org.fife.rsta.ac.perl.PerlLanguageRegistration +org.fife.rsta.ac.sh.ShellLanguageRegistration +org.fife.rsta.ac.java.JavaLanguageRegistration \ No newline at end of file diff --git a/src/main/resources/org/fife/rsta/ac/bsh/img/abstract_co.gif b/src/main/resources/org/fife/rsta/ac/bsh/img/abstract_co.gif new file mode 100644 index 0000000000000000000000000000000000000000..533acc4326632a698fa12102da6a879c597c0cdc GIT binary patch literal 79 zcmZ?wbhEHbWM|-DSj4~}Qe|P#6;Qoz($2d_uf4we9}E~67!-f9FfuT(G3Wr<3?Q`( d%pw_K0lSzuwnqi)I3GyYi)Rpfl%d984FF4S8F>Hz literal 0 HcmV?d00001 diff --git a/src/main/resources/org/fife/rsta/ac/bsh/img/class_default_obj.gif b/src/main/resources/org/fife/rsta/ac/bsh/img/class_default_obj.gif new file mode 100644 index 0000000000000000000000000000000000000000..4244a7f39d32695bf6e435665a8775ca8458ff19 GIT binary patch literal 604 zcmZ?wbhEHb6krfwc*ejG(zwmBe0@;cuHd#^aw&_I)0bG5Z?LS`AP_T0C~mH3{5-LQ z`I5;CWKtH%q%M+4StygbP%d?`QpQrX?B(h?%iWtchc7J5UDvYi(r)7>U$_3asM!T& z>pJQ-PiWja>BNHzXCGa;{_?I$nVnvZn{lJJWm`b(yu#!~<;%`&y7lV5ZjFmxt*d^m zn?W5=*3)}Zg4cw&@^$Ssn|hkIPS|_v=#7_mjT+p|TD+{={p~x0`u5J6eQcRshreA% zfL(ilTVHt4w506iRsH*B9lm?=(fg-ivr@ulrtGo_~DSg5$Gy-`IZW&i-Tf4sW=y`ac*j zkPZ}ovM@3*#VJ%rLAXf zqq4`sFxSP>&d$hK!&;_U-PY4D*WJ-7*GEKHzS&gCBhYK5H!BmfP>-y#{XB<>Oi#HQ znc0*~UL9ca5L7nNvMFF#$k^RsX(Ohwq+z^!{nkw1lu( zDPc2HV&`P7KEHX-jYA>R6T@ewM9fTyo0E0x)!k_2wz@P-Sk|APSoeSzXn7Dfh!ClGm2|QYKe-7h)T#Q@$He9j?`9AQ4ux} zP&?5iq-<&#X{ezXX|J!t&@97aWMj6{+|Gn&T@xp-YRQ`y8=a5yFmmdtZYWsP+AXH8 bqq4{4!~q5-W`Qq@Pi$O#yuX);k--`O+yTtY literal 0 HcmV?d00001 diff --git a/src/main/resources/org/fife/rsta/ac/bsh/img/constr_ovr.gif b/src/main/resources/org/fife/rsta/ac/bsh/img/constr_ovr.gif new file mode 100644 index 0000000000000000000000000000000000000000..3977bc0ffec8eace3fe70f66df5f07570fc1068e GIT binary patch literal 81 zcmZ?wbhEHbWM|-DSj51fzurr!&Q!6=#9>=x|HB2l-yZ!B28usf7#SGY8FUzc0Hl_I fS*(Ihs5IR|Xo1NMww#iM7cSW(vdv9rVz34PWSJV( literal 0 HcmV?d00001 diff --git a/src/main/resources/org/fife/rsta/ac/bsh/img/deprecated.gif b/src/main/resources/org/fife/rsta/ac/bsh/img/deprecated.gif new file mode 100644 index 0000000000000000000000000000000000000000..d03b6a99d68d980ae30f19972c11cf131b459c64 GIT binary patch literal 78 zcmZ?wbhEHb6krfwn8?7;SX{Gw(aI~AuKxf3U-2gkBLf37gAM}_faDpNY z#nrw`YXg_o1um-(UfCS6sx^8;Z`!5_Sz9LOZJSoKb5{ATIaRyo*6dr@cwkBEq2-;& z*G)RJZSJ`p3ohPvx>T&-ZHD*dWJeG%`%eW;>(wr$SO$hkiW3Z&dkif$?0&Dp@O>l zGV8m}BEl{U#WXcfy0bDd3-wrtE8Bdrabsa;6YRB+(9qG=GN^dK;Ka<<+qHs2QK_Se dL4a9jhlvJbL$`!*fJ@VY#mD=k&Doe3tO3R#riuUn literal 0 HcmV?d00001 diff --git a/src/main/resources/org/fife/rsta/ac/bsh/img/enum_obj.gif b/src/main/resources/org/fife/rsta/ac/bsh/img/enum_obj.gif new file mode 100644 index 0000000000000000000000000000000000000000..15535f52f52b20b465a9adbe6c766edffc0a287c GIT binary patch literal 361 zcmZ?wbhEHb6krfwxXQrL6RFS_qtX|v+8?VnAx?clyvD=?%}I&claqBPr|3^fHJF-i zG(E#~Mz+Pw9Lrg`Hna2X<`p~7D{+}$>bjuJePOxB!g9~W)xJw={Fl}SF0Bh(Rv)~w zIbv07^!o0U4ZUfbCS+}yoVRUS(au@ryXI8wo?EkTVdH@%t%sI(9$z=<%(l7bb}YEK zXX%aOTOM9M^8eqz|Ns9pkOCBcvM@3*7%=F7G=coYz}Dt4L*UsZ2Lb-x>=P|h1!TLo zBx{(?ZMm4W`z^y7XK^Kws+nhXx)U|`GaEA_V|tnb zI~QvO=Y%vZB_-(z%}z30f`V!4a~8-YG6)NI>Sr?KIH@r5YHZjb%dQfx!XzXnDkj9V XHQYsnn}=Is^??&7Po4I4WUvMR>jHhA literal 0 HcmV?d00001 diff --git a/src/main/resources/org/fife/rsta/ac/bsh/img/enum_private_obj.gif b/src/main/resources/org/fife/rsta/ac/bsh/img/enum_private_obj.gif new file mode 100644 index 0000000000000000000000000000000000000000..4d839591970d4e3e137979df7e8e4dde244fac4b GIT binary patch literal 590 zcmZ?wbhEHb6krfwc*el+JR$LfrojmVlM|YTCuDU#`Nn+ojrm&Ea6(e+=E-fh&+K}3 z`&>_?LSKwZU#x0>tlES)^$GDB6B9HiC2CJj)}5T9KPA;*YP!*kY>SyWma}qgX6M_@ zD|Vh&;xfO~bwQc?!g9~W)xJw>1DDnXE~^h-*&MN|HF`sD+NKFvTPEl2oK?PSPSx(Y zHTxDe9$MaceBGoo+vc9zvEbsKrB@EFxq5irwIdsD9N+Tr@{vbZk3YY2;rZn5lg>6L z-R(}=S$&(-_dFrtYfa7D=H~zZ{{067hM@)&f3h$#Ft{-2fE*5r69)Fx4K7VC=E~9{ zQp)DdJuW&TY6_FogmilQ1hfoi&sO7^)@&}Ksp+(AnUR7}cax&Z`ekPN`s(Xdn3@S@2s$w!S%eZYGKC)>t=aG|J=4@m4 z_N{fZHm`)9o~5mw!!JAA9&J8Z2Ni*W0}hPL>?|g`K0ajXWpu0qI!@)lQb(4Oj4K@v R7AdeOIG25SVJN_04FHc$twR6+ literal 0 HcmV?d00001 diff --git a/src/main/resources/org/fife/rsta/ac/bsh/img/enum_protected_obj.gif b/src/main/resources/org/fife/rsta/ac/bsh/img/enum_protected_obj.gif new file mode 100644 index 0000000000000000000000000000000000000000..834aa853fc59192c2e9ed7c7d203924f1922d9d8 GIT binary patch literal 586 zcmZ?wbhEHb6krfwc*el+|I>#5FDL$gHF5i7)qQg`cF$1XJyZSvvl;8!6Qr87#?hDI37gzf( ztqojS7r3lGcx7|Ms@CWYy=j{!WNn$8w{2R{&RONV=2Y#TTeELrE#2ft{z%@<=~oYM>gCzzUATNBhT+#`2X+U|Ns9Ph6qsn$->CM;Le}} zaxW-O7}%FLxHq}G=&H)9=(;rbxSPuwXiYMZG4Jh@GPRvO+dynuvx}^;vD>m`c3Lvs zP1<_vmpNNo8?M)HR#wx|S!S_YM_)_1Sw>P^eEBjXdq?RVau=4_n3#yNusAjA%d4p^ zvs80tVPIfcD5jxtl9lN#BU`hXxRRBXD>pmOFCKR0j}q!30RaMuO$Rvzg$$G?F}ZLk c2&i~WX?PH%%q}D!vFFNygU9-tm>3zX0S{5Ju>b%7 literal 0 HcmV?d00001 diff --git a/src/main/resources/org/fife/rsta/ac/bsh/img/error_obj.gif b/src/main/resources/org/fife/rsta/ac/bsh/img/error_obj.gif new file mode 100644 index 0000000000000000000000000000000000000000..0bc60689c6dcbfb71770789a3c2e98f51f6eecd7 GIT binary patch literal 339 zcmZ?wbhEHb6krfwxXQrrHNWU4 z&?^&f5)>{J;LlXy?-r0R|L*vM@3*urTO=1VCyTm}NY6-T7y5 e%JVgg#C-#%9nL>I8Pt0Mmqq5h-si)_U=0A%@f=A2 literal 0 HcmV?d00001 diff --git a/src/main/resources/org/fife/rsta/ac/bsh/img/field_protected_obj.gif b/src/main/resources/org/fife/rsta/ac/bsh/img/field_protected_obj.gif new file mode 100644 index 0000000000000000000000000000000000000000..3377b1ebe7e36d3956926b027d48bb8765d768e2 GIT binary patch literal 119 zcmZ?wbhEHb6krfw*v!DNZ;r<98S1-ds;_I8-`uOTsaI)voy@96*;P$)>)I9m-JACB ze9nI`U;qQfpDc_F47?0FARfpJ1{ReKCp}m1wRnBj^abyNn&<@vT?<6HAM3SD+j9DV PEH{%>!u$U-IT)+~%PKA; literal 0 HcmV?d00001 diff --git a/src/main/resources/org/fife/rsta/ac/bsh/img/field_public_obj.gif b/src/main/resources/org/fife/rsta/ac/bsh/img/field_public_obj.gif new file mode 100644 index 0000000000000000000000000000000000000000..d4cb4254d92bcafa0341fc69e353c8cafe6944fe GIT binary patch literal 124 zcmZ?wbhEHb6krfw*v!Bn(B^A0Bg183N$uYG6Hly@>kKN~SlYRx@jn~j5E5CelX06bS3^Z)<= literal 0 HcmV?d00001 diff --git a/src/main/resources/org/fife/rsta/ac/bsh/img/imp_obj.gif b/src/main/resources/org/fife/rsta/ac/bsh/img/imp_obj.gif new file mode 100644 index 0000000000000000000000000000000000000000..9e44ce52a99dc349ce4f9248aebbe908feb3cdfb GIT binary patch literal 114 zcmZ?wbhEHb6krfw*v!DNW%tD;>rSrQc6R2{!{wbDd*|$Jn!G)?c@3jml}<``cK_1< z|Nk=}0mYvzj0_Ci3_2h&kQodt@&zY7SMRlWeRln;?xqqiqdcXeCT;~5=R^Va?E4kx HTp6qZsc9$& literal 0 HcmV?d00001 diff --git a/src/main/resources/org/fife/rsta/ac/bsh/img/impc_obj.gif b/src/main/resources/org/fife/rsta/ac/bsh/img/impc_obj.gif new file mode 100644 index 0000000000000000000000000000000000000000..ea94702caff9d46b70fc7a6b341b6ada7bf0d612 GIT binary patch literal 185 zcmZ?wbhEHb6krfwIKsfNdh?kryDu(Ub7IN5lWVq~UAOJ*)P)CTEvbMZ)V_pB& z_GvqN=j@%k@@RhZ+RC2IO_R6hHm_lHtI|p7&hB6O|Nnmmyg>0M3nK%AD1#12706Bo zRU$_3asM!T& z>pJQ-PiWja>BNHzXCGa;{_?I$nVnvZn{lJJWm`b(yu#!~<;%`&y7lV5ZjFmxt*d^m zn?W5=*3)}Zg4cw&@^$Ssn|hkIPS|_v=#7_mjT+p|TD+{={p~x0`u5J6eQcRshreA% zfL(ilTVHt4w506iRsH*B9lm?=(fg-ivr@ulrtGo_~DSg5$Gy-`IZW&i-Tf4sW=y`ac*j zkPZ}ovM@3*#VJ%rLAXf zqq4`sFxSP>&d$hK!&;_U-PY4D*WJ-7*GEKHzS&gCBhYK5H!BmfP>-y#{XB<>Oi#HQ znc0*~UL9ca5L7nNvMFF#$k^z19_q+8>n zSL>=@>t;{~l=bwUl;AZXu6$kljhA(?K^{JA6sVE;cwRwVAmet))yW$ zEh&3>RsX(OOHQvneD~y|_fNxSrK~=`dC!eQA=4A%=49P^bvI~Q+{f>q5*B3EY-*`o z*SP%5n#h@n8B6jL7o;c5OPhCW;hk4^(-&psE-NTsSJAM!p?YIg<+}3r9j%RkbJE@Jq@C5bNqx@~ z628{dylrm&4+ac01ByRc7#SE68FWB4fZ~LKeMduLQ=*W#f|#PXP;*bBfS7~(BnK{m z-aZwd@X)Z(U=QJG%|c>cfe9;C1bA|FH}N?JtqAe+Pw@42lxXI$bWU(_I^^c+YR}Wm zC8wWYC?hQ`Bd@9{x<^eZ!AMWKv>P Pj5sOecxrkh1A{dHf3)AB literal 0 HcmV?d00001 diff --git a/src/main/resources/org/fife/rsta/ac/bsh/img/innerclass_protected_obj.gif b/src/main/resources/org/fife/rsta/ac/bsh/img/innerclass_protected_obj.gif new file mode 100644 index 0000000000000000000000000000000000000000..5105577d5b3e17cfc345bfe5f1141cfd54886190 GIT binary patch literal 600 zcmZ?wbhEHb6krfwc*ekB+~n)f8R66&<<=h;G9xQ$c0t|d35{DP%|5nr%a#3SA6-!? zv(u|_Gj8;@Yzy$8ni@N=FnLkAZjFmxt*d^mn?aqM_oM``330*G({oqUm9J~R@$#-w zgS&ORzkO%Wg#B~uIs)w41Kj$;gQg{AFR$v~H*4CVg-cGaJ$(1%qxVn4W~J=8aVTVZ zV%(gpTd(d0O^f^Z{Zq*FxP%3nHJe&0*EKFbvnFz8V#bpE#0BXI^U~%WTX^Ty-P~mb z)Cv1!=9Tv_ubk(|M;v0$7k=pvHj4U{m1Sd z-f&^{|4$qKznu90)x_RsX(Ohwq+z^!{nkw1lu( zDPc2HV&`P7KEHX-jYA>R6T@ewM9fTyo0E0x)!k_2wz@P-Sk|APSoeSzXn7Dfh!ClGm2|QYKe-7h)T#Q@$He9j?`9AQ4ux} zP&?5iq-<&#X{ezXX|J!t&@97aWMj6{+|Gn&T@xp-YRQ`y8=a5yFmmdtZYWsP+AXH8 bqq4{4!~q5-W`Qq@Pi$O#yuX);k--`O+yTtY literal 0 HcmV?d00001 diff --git a/src/main/resources/org/fife/rsta/ac/bsh/img/innerinterface_default_obj.gif b/src/main/resources/org/fife/rsta/ac/bsh/img/innerinterface_default_obj.gif new file mode 100644 index 0000000000000000000000000000000000000000..ab1b576aad56948855c66e6e41109e4b26d06105 GIT binary patch literal 595 zcmZ?wbhEHb6krfwc*ekRbkBpMd+%L1`Skk5mj!Vf@?+N(C2TB=-%y;mu{334McS6y zoE^0}+nb7ZwwCSeZ#Xo)pqcgjY&zpF9PXEdIlTI(4d49#53oGWFU%lYsx+NDk zF2AyU?Ty2`?_E9r;?DIqkM4a4b($aLK0nrLNtDO@NcVX$o(tlGLuSgA9nG?M>J9tnsAD%h(B+hSPX5^Z6ORt19ZgVVOAJn!hxNVnQ%3|g8C6?tIEGsq$ z#LN+jn=2YWPb^`+Wby);ltnVBi)2z3%A_uoOI@s#u~aR4xq8m>|6ssCU!eGtg^__F zia`ftEhtVH*f%spHAOiHu(7ZUI5hV}*|2c)PvT~=>FqPL7IU5>W^FjFSzgOrJaTy? zv$&;}e6s+LnVIl%hD~O?BF!95toxSR?K3v!Xx3HJP*q(nbxK1?XScSdipp|Z6+Q_G zp=J>SJ$=XJ(vGqb;Y`g6iY68-A{jm1+{1cAmAR~bTgiENd#y5ARj|mdiA83C&qOCx pt|@K~N+(WyIP5vG+jU-y)RmTwT#EqpX8!OVb)aLA{&Dq{mw6nkA(DaUDQ`?Wun|OLo|H=82PA{E# ze#M*%E9RVEKKtzI1sB&Xxp?RLn@9IPggVWSa-SdTwIs@8ex&=n7|#W9-b-S=7RGun zO!Qx#;J+-(g;UQgpL2fQ(o0*{+}OF{)|q2Z;`|n7My^@6^vd(e-6x%GPP*Hjw6pp) zsqcA0!q=Lbx6RG}!GK}V0L7myj0_Bc3_2hef#QULeSJecSV%1A++-ml+05_8vv0ZcK2uZv zW_=AUb@k;6r?gb`cI#@ZsV#SOkdu{lYL+xIFmzq+_4JunlajKT)e0}44<9_6rBnrN zY~;Ot{QmlQ_n0i%!FaH}ftigUS)^DMB|L>v LPE2TIV6X-NbK1oU literal 0 HcmV?d00001 diff --git a/src/main/resources/org/fife/rsta/ac/bsh/img/innerinterface_protected_obj.gif b/src/main/resources/org/fife/rsta/ac/bsh/img/innerinterface_protected_obj.gif new file mode 100644 index 0000000000000000000000000000000000000000..f58eef07c1d88f51322f1aca48f5e875034e4c5a GIT binary patch literal 592 zcmZ?wbhEHb6krfwc*ekRbkBq97he{{ZOD&ZSCp`^Fn&XE;>OaHjTLEIYIAnf=4@{& z+S%W5XnM!7sqIJSO*}oP|K$8hr~1Em;+>-UA^GqrsY@HExEXH`IYT! zZ``^5=Fzy}>Hy5`2t z4Y$r5dlKijFf($^x}{hCf7<;4H5CT^dsx^Irg?iuR4XR7~yHe+48{N`SzO}$Dx zCae6vSG&AUW>ur?swTO0?F#>H_x!sz?ce#F|6sr{a6s`V3nK$V7=sST37|M(U|-u1 z))Z#T%fiIUYunrtX2HbCGl`SQqPI`iT*zULkh$)(W*IeOkSLChp_m%P?C(u_)iAhgo`>$HGGsxsn$Z9h7r>-fBhr|0yaoImOGqG@NA&OE%B11e|ducvPA!7Nde1Kf>tC2EKTrV zloGT&HF!m8$jY4Pwb{{Ya$?pLCTz@)TUVO0skvlNXVw0;irw9{`@3rP^)(z^IQ7iB zrI&VYxOL{(lQ_SHnUQPOExqy|3>bzWQ2fcl$iU#tpaXI{C{7sIXE!)EIot8EGPCj7 zHTO7MGjs7y;$pV$?bEXob(|w=r8livQq@e%X}J@Vn1!ljGat99so-*kO{P3T&Fl^= z`pqcgjY&zpF9PXEdIlTI(4d49#53oGWFU%lYsx+NDk zF2AyU?Ty2`?_E9r;?DIqkM4a4b($aLK0nrLNtDO@NcVX$o(tlGLuSgA9nG?M>J9tnsAD%h(B+hSPX5^Z6ORt19ZgVVOAJn!hxNVnQ%3|g8C6?tIEGsq$ z#LN+jn=2YWPb^`+Wby);ltnVBi)2z3%A_uoOI@s#u~aR4xq8m>|6ssCU!eGtg^__F zia`ftEhtVH*f%spHAOiHu(7ZUI5hV}*|2c)PvT~=>FqPL7IU5>W^FjFSzgOrJaTy? zv$&;}e6s+LnVIl%hD~O?BF!95toxSR?K3v!Xx3HJP*q(nbxK1?XScSdipp|Z6+Q_G zp=J>SJ$=XJ(vGqb;Y`g6iY68-A{jm1+{1cAmAR~bTgiENd#y5ARj|mdiA83C&qOCx pt|@K~N+(WyIP5vG+jU-y)RmTwsn$Z9h7r>-fBhr|0yaoImOGqG@NA&OE%B11e|ducvPA!7Nde1Kf>tC2EKTrV zloGT&HF!m8$jY4Pwb{{Ya$?pLCTz@)TUVO0skvlNXVw0;irw9{`@3rP^)(z^IQ7iB zrI&VYxOL{(lQ_SHnUQPOExqy|3>bzWQ2fcl$iU#tpaXI{C{7sIXE!)EIot8EGPCj7 zHTO7MGjs7y;$pV$?bEXob(|w=r8livQq@e%X}J@Vn1!ljGat99so-*kO{P3T&Fl^= z`{Kt z;|);i%kO(He%ycY{qgG`&))ug`TpnIPrp8Y0}6hB`0B^QSKnWK`1#?>ukSzqeEaeH z!K)vS-~4#<>DT)&zu$iPnLT08vv)sUe)#$6+wV7@e%ci+|N7&%M$)vb1xL4EdUE{X z+nNHq>U_KE0=t$Ho0@#P&NAzcGV9i2o2EjW#zLF=0^8}e=98)|CRbbbm0R|fTdrs` zUfN=^q}gOalj-~>(>e7(WHznF{K1L-OB6H%fccxUqMYu&8F2}SXg;ABcrfgs{;cw&uR$%J) zN~@K`l`L8<6}2=p76>SES+yGSYpE{aqkrFxY3xL6ph0Z8G|RR910 literal 0 HcmV?d00001 diff --git a/src/main/resources/org/fife/rsta/ac/bsh/img/jdoc_tag_obj.gif b/src/main/resources/org/fife/rsta/ac/bsh/img/jdoc_tag_obj.gif new file mode 100644 index 0000000000000000000000000000000000000000..c43c5d51c5164161fbbfa35391f86f03f420b4e4 GIT binary patch literal 323 zcmZ?wbhEHb6krfwxXQrr;{CVP$L{UE`1Ib(&n6|S^)hByRjf76nqiqUBVpR%?71fj z7M`qMd8TvYrJhZfXY9T?XYZ}K`)+PN^JvT2N88Uo*>~mniQBJ_-+FcD#V3Z)>3Iu| zSFbp;;K0r0NAEs;_vJqrFwhbx{$ycfU{GMt0a*g_69Zdg1lb);hTDFLZjLs&~-@&N7aU#yw3L zj6O*!7R)g$izT`gnhO|N#M)YoHf)w*<7u8^I3bd&xuGoJf(!$5!&GOzd?f~J0FXsH AVE_OC literal 0 HcmV?d00001 diff --git a/src/main/resources/org/fife/rsta/ac/bsh/img/methdef_obj.gif b/src/main/resources/org/fife/rsta/ac/bsh/img/methdef_obj.gif new file mode 100644 index 0000000000000000000000000000000000000000..f4a1ea1507068ad913d6151b496e2b303bec9dfe GIT binary patch literal 176 zcmZ?wbhEHb6krfwIKsdX(zwmBe0@;cuHd#^aw&_I)0bG5Z?LS`AP_T0C~mH3{5-LQ z`I5;CWKtH%q%M+4StygbP%d?`QpQrX?B(h?%m4rX&wv*w{$ycfU=U@{0jUDn$-t_c zpxT#`IWJ??x}4KN!O#5FDL$gHF5i7)qQg`cF$1XJyZSvvl;8!CMAi|&nQV6n>fz?Ps zwJ#-eUdF0*IbH&~j0_v1I4TmBoId!c=P<+44xhfs9!jheEmS+E9{!nODz$daHc=)9 FYXDFdK#l+a literal 0 HcmV?d00001 diff --git a/src/main/resources/org/fife/rsta/ac/bsh/img/methpub_obj.gif b/src/main/resources/org/fife/rsta/ac/bsh/img/methpub_obj.gif new file mode 100644 index 0000000000000000000000000000000000000000..7d24707ee82f54aa9fb10d1d9050013cbf161a7a GIT binary patch literal 193 zcmV;y06zamNk%w1VGsZi0K@VRxXubL!4|)qjO}gg>klxZ?TGXw~#-V zU_Y2&N}FX?r*L1YbYiM-aj|xBv2}#Mgo3?-guaA=wSS1Yfrz+)iMWB7#*ml2h^x<; ztIwFU(w+bR{{R30A^8LW0015UEC2ui01yBW000F(peK%GX`X1Rt}L1aL$Vf5mpMgx vG+WO#2NYmJDM}^)l;8n@L?90V%CN9pFcyU&MPO(u48jTlL$uClRtNw)MiWcq literal 0 HcmV?d00001 diff --git a/src/main/resources/org/fife/rsta/ac/bsh/img/package_obj.gif b/src/main/resources/org/fife/rsta/ac/bsh/img/package_obj.gif new file mode 100644 index 0000000000000000000000000000000000000000..131c28da405493661e3253ef79a68bd273039295 GIT binary patch literal 227 zcmZ?wbhEHb6krfwIKsg2^W*Nf7neOfxp04z;n8NJ+xzDotkS){bH@Hst%K#-*LO_c zo~yCDQ0v_4?v)A3lSAd#C95utQCbkGxF}NT_=2WF8}WGs5taT9|NsAIzy=h5vM@3* zNHFMtBtdpEuqG&|^`&Ia(}-MpBVo@mW@+b{B25<}cFdc?!Kkoc14n0vkh1`XOwU>7 z#al8o_@;D=?hdfkdC)D9Q@O@%Lfqp;ZBt~9C*29`GMF2XzQp8akWQVjDvMC75PzEx Mi%z;upCW@b03m@=3jhEB literal 0 HcmV?d00001 diff --git a/src/main/resources/org/fife/rsta/ac/bsh/img/static_co.gif b/src/main/resources/org/fife/rsta/ac/bsh/img/static_co.gif new file mode 100644 index 0000000000000000000000000000000000000000..499664d57b815ab80fba7be589508e2fa9205eab GIT binary patch literal 79 zcmZ?wbhEHbWM^P!Sj50^oJsdt?}86|j{gS(1{hHM$->CMz`~#d5&)@XU>5OEW-#LF VQG7h7%d$dq`aB_%gA*7StO3qo7J&c& literal 0 HcmV?d00001 diff --git a/src/main/resources/org/fife/rsta/ac/bsh/img/synch_co.gif b/src/main/resources/org/fife/rsta/ac/bsh/img/synch_co.gif new file mode 100644 index 0000000000000000000000000000000000000000..5893bda59c77d7af3a30b1788d32d331c21b7713 GIT binary patch literal 165 zcmZ?wbhEHbWM|-DIKsg2_uqep&}k;+t54s3Ws=|j>G%H|U;f|y`v2*V|8IW%fBWnI zmp}i%|NZ~_-~Ug4{zCu*DM0Zj3nK%A0D}%l6Ua^mR;35V9E}DYjEmTmFR}1C$gw^& XSUOSTND^D0g13v2ZQqGx4hCxgA_6<5 literal 0 HcmV?d00001 diff --git a/src/main/resources/org/fife/rsta/ac/bsh/img/template_obj.gif b/src/main/resources/org/fife/rsta/ac/bsh/img/template_obj.gif new file mode 100644 index 0000000000000000000000000000000000000000..fdde5fbb95e50851757a749194ce6a3431bb1afb GIT binary patch literal 359 zcmZ?wbhEHb6krfwxXQp#S5Vbd+T2kyvA<>Ew4RM~ChuP`<3xJx%B+Sp`K{~Ax;NKM z+|e|BZ|B^Dy$g@DOoEfOLTT#K6{aU`Bz54qxJl zB|@GpTjyQSSo6|If~%!bfuX>+fBlAvKcbsVUTm4=8k1@Bp`yk$BvY-AEqS4bf{m7o zrj)XDt5U17vZjknd1ZAihrEo7sFZ?&?95rSL|sJ6g}6D{6_=}sxClzAimPr=lTcF? dbPViCtV#GtN}CUpjiL_ literal 0 HcmV?d00001 diff --git a/src/main/resources/org/fife/rsta/ac/bsh/img/warning_obj.gif b/src/main/resources/org/fife/rsta/ac/bsh/img/warning_obj.gif new file mode 100644 index 0000000000000000000000000000000000000000..2b2e50fe7cbca2cc105047ed184e3073f0c24fc3 GIT binary patch literal 324 zcmZ?wbhEHb6krfwxXQrr|8~*;dyW4e_5Od<|NqIf|Bt8te>(U7vw8pD9sGYH>i^m7 z{}+n?Uupb*wdw!W=Kpu5|Gzi)|MMOH&*W4G3O9s`Hie5dhKhAYOSDHz^u$R`Ns&F; ztb4Lu|5%IOu~xma-9{(d4NrF&pY1liGsFJ=Y^MivoF6U?J>712zT5O-ui5SC4)jB<~Eh3Ck(|MR1tY+CYw%7@BZ0uHG65^MT;^$&kcave^ j77&vV;AWL^lhtKopEXNY&Ru%J!UdsAmM(L0WUvMR>~MP$ literal 0 HcmV?d00001 diff --git a/src/main/resources/org/fife/rsta/ac/bsh/resources.properties b/src/main/resources/org/fife/rsta/ac/bsh/resources.properties new file mode 100644 index 00000000..4fbf68c7 --- /dev/null +++ b/src/main/resources/org/fife/rsta/ac/bsh/resources.properties @@ -0,0 +1,26 @@ +sysout.shortDesc=print to standard out +sysout.summary=System.out.println(); +syserr.shortDesc=print to standard error +syserr.summary=System.err.println(); +for.array.shortDesc=iterate over array +for.array.summary=for (int i = 0; i < array.length; i++) {

    }
    +for.loop.shortDesc=iterate +for.loop.summary=for (int i = 0; i < 10; i++) {

    }
    +do.shortDesc=do-while statement +do.summary=do {

    } while(condition);
    +runnable.shortDesc=runnable +runnable.summary=new Runnable() {
    public void run() {
    }
    }
    +if.cond.shortDesc=if statement +if.cond.summary=if (condition) {

    }
    +if.else.shortDesc=if-else statement +if.else.summary=if (condition) {

    }
    else {

    }
    +while.shortDesc=while condition +while.summary=while (condition) {

    }
    +todo=A to-do reminder +fixme=A bug that needs to be fixed +switch.case.shortDesc=switch case statement +switch.case.summary=switch (key) {
     case value:

          break;

      default:
          break;
    } +try.catch.shortDesc=try catch statement +try.catch.summary=try {

    }
    catch (err) {

    } +catch.block.shortDesc=catch block +catch.block.summary=catch (err) {

    } From cedca406cfb9d51416cae091e1d18ff2b76c3b07 Mon Sep 17 00:00:00 2001 From: Matthew Aguirre Date: Thu, 17 Sep 2015 11:51:50 -0400 Subject: [PATCH 2/5] Removed BeanShell --- .../ac/bsh/AbstractJavaSourceCompletion.java | 81 - .../org/fife/rsta/ac/bsh/ClassCompletion.java | 232 --- .../org/fife/rsta/ac/bsh/DecoratableIcon.java | 155 -- .../ac/bsh/DocCommentCompletionProvider.java | 121 -- .../org/fife/rsta/ac/bsh/FieldCompletion.java | 180 -- .../java/org/fife/rsta/ac/bsh/FieldData.java | 139 -- .../org/fife/rsta/ac/bsh/FieldInfoData.java | 212 --- .../org/fife/rsta/ac/bsh/IconFactory.java | 180 -- .../java/org/fife/rsta/ac/bsh/JarManager.java | 433 ----- .../java/org/fife/rsta/ac/bsh/JarReader.java | 162 -- .../fife/rsta/ac/bsh/JavaCellRenderer.java | 210 --- .../rsta/ac/bsh/JavaCompletionProvider.java | 193 -- .../rsta/ac/bsh/JavaLanguageRegistration.java | 27 - .../fife/rsta/ac/bsh/JavaLanguageSupport.java | 594 ------ .../fife/rsta/ac/bsh/JavaLinkGenerator.java | 268 --- .../ac/bsh/JavaParamListCellRenderer.java | 69 - .../java/org/fife/rsta/ac/bsh/JavaParser.java | 164 -- .../rsta/ac/bsh/JavaShorthandCompletion.java | 110 -- .../ac/bsh/JavaShorthandCompletionCache.java | 95 - .../rsta/ac/bsh/JavaSourceCompletion.java | 45 - .../rsta/ac/bsh/JavaTemplateCompletion.java | 70 - .../fife/rsta/ac/bsh/JavadocUrlHandler.java | 371 ---- .../rsta/ac/bsh/LocalVariableCompletion.java | 73 - .../fife/rsta/ac/bsh/MemberCompletion.java | 111 -- .../fife/rsta/ac/bsh/MethodCompletion.java | 332 ---- .../java/org/fife/rsta/ac/bsh/MethodData.java | 121 -- .../org/fife/rsta/ac/bsh/MethodInfoData.java | 371 ---- .../org/fife/rsta/ac/bsh/PackageMapNode.java | 385 ---- .../rsta/ac/bsh/PackageNameCompletion.java | 58 - .../rsta/ac/bsh/SourceCompletionProvider.java | 1072 ----------- .../ac/bsh/SourceParamChoicesProvider.java | 337 ---- src/main/java/org/fife/rsta/ac/bsh/Util.java | 728 -------- .../bsh/buildpath/ClassEnumerationReader.java | 112 -- .../bsh/buildpath/ClasspathLibraryInfo.java | 220 --- .../buildpath/ClasspathSourceLocation.java | 70 - .../rsta/ac/bsh/buildpath/DirLibraryInfo.java | 195 -- .../ac/bsh/buildpath/DirSourceLocation.java | 96 - .../rsta/ac/bsh/buildpath/JarLibraryInfo.java | 214 --- .../rsta/ac/bsh/buildpath/LibraryInfo.java | 283 --- .../rsta/ac/bsh/buildpath/SourceLocation.java | 53 - .../ac/bsh/buildpath/ZipSourceLocation.java | 104 -- .../rsta/ac/bsh/classreader/AccessFlags.java | 109 -- .../rsta/ac/bsh/classreader/ClassFile.java | 772 -------- .../bsh/classreader/ExceptionTableEntry.java | 126 -- .../rsta/ac/bsh/classreader/FieldInfo.java | 279 --- .../fife/rsta/ac/bsh/classreader/Frame.java | 117 -- .../rsta/ac/bsh/classreader/MemberInfo.java | 188 -- .../rsta/ac/bsh/classreader/MethodInfo.java | 721 ------- .../fife/rsta/ac/bsh/classreader/Util.java | 102 - .../classreader/attributes/AttributeInfo.java | 70 - .../ac/bsh/classreader/attributes/Code.java | 305 --- .../classreader/attributes/ConstantValue.java | 103 - .../classreader/attributes/Exceptions.java | 88 - .../bsh/classreader/attributes/Signature.java | 424 ----- .../classreader/attributes/SourceFile.java | 73 - .../attributes/UnsupportedAttribute.java | 65 - .../constantpool/ConstantClassInfo.java | 69 - .../constantpool/ConstantDoubleInfo.java | 73 - .../constantpool/ConstantFieldrefInfo.java | 64 - .../constantpool/ConstantFloatInfo.java | 64 - .../constantpool/ConstantIntegerInfo.java | 62 - .../ConstantInterfaceMethodrefInfo.java | 66 - .../ConstantInvokeDynamicInfo.java | 63 - .../constantpool/ConstantLongInfo.java | 67 - .../ConstantMethodHandleInfo.java | 62 - .../constantpool/ConstantMethodTypeInfo.java | 52 - .../constantpool/ConstantMethodrefInfo.java | 64 - .../constantpool/ConstantNameAndTypeInfo.java | 63 - .../constantpool/ConstantPoolInfo.java | 47 - .../constantpool/ConstantPoolInfoFactory.java | 127 -- .../constantpool/ConstantStringInfo.java | 69 - .../constantpool/ConstantTypes.java | 50 - .../constantpool/ConstantUtf8Info.java | 135 -- .../org/fife/rsta/ac/bsh/rjc/ast/ASTNode.java | 53 - .../rsta/ac/bsh/rjc/ast/AbstractASTNode.java | 94 - .../rsta/ac/bsh/rjc/ast/AbstractMember.java | 63 - .../rjc/ast/AbstractTypeDeclarationNode.java | 288 --- .../fife/rsta/ac/bsh/rjc/ast/CodeBlock.java | 203 -- .../rsta/ac/bsh/rjc/ast/CompilationUnit.java | 290 --- .../fife/rsta/ac/bsh/rjc/ast/EnumBody.java | 46 - .../rsta/ac/bsh/rjc/ast/EnumDeclaration.java | 36 - .../org/fife/rsta/ac/bsh/rjc/ast/Field.java | 68 - .../rsta/ac/bsh/rjc/ast/FormalParameter.java | 61 - .../ac/bsh/rjc/ast/ImportDeclaration.java | 48 - .../rsta/ac/bsh/rjc/ast/LocalVariable.java | 47 - .../org/fife/rsta/ac/bsh/rjc/ast/Member.java | 63 - .../org/fife/rsta/ac/bsh/rjc/ast/Method.java | 148 -- .../bsh/rjc/ast/NormalClassDeclaration.java | 142 -- .../rjc/ast/NormalInterfaceDeclaration.java | 63 - .../org/fife/rsta/ac/bsh/rjc/ast/Package.java | 24 - .../rsta/ac/bsh/rjc/ast/TypeDeclaration.java | 173 -- .../bsh/rjc/ast/TypeDeclarationContainer.java | 27 - .../fife/rsta/ac/bsh/rjc/lang/Annotation.java | 30 - .../fife/rsta/ac/bsh/rjc/lang/Modifiers.java | 193 -- .../org/fife/rsta/ac/bsh/rjc/lang/Type.java | 193 -- .../rsta/ac/bsh/rjc/lang/TypeArgument.java | 61 - .../rsta/ac/bsh/rjc/lang/TypeParameter.java | 57 - .../fife/rsta/ac/bsh/rjc/lang/Variable.java | 51 - .../fife/rsta/ac/bsh/rjc/lexer/Offset.java | 33 - .../fife/rsta/ac/bsh/rjc/lexer/Scanner.java | 870 --------- .../ac/bsh/rjc/lexer/SourceCodeScanner.flex | 393 ---- .../ac/bsh/rjc/lexer/SourceCodeScanner.java | 1663 ----------------- .../org/fife/rsta/ac/bsh/rjc/lexer/Token.java | 55 - .../fife/rsta/ac/bsh/rjc/lexer/TokenImpl.java | 167 -- .../rsta/ac/bsh/rjc/lexer/TokenTypes.java | 141 -- .../rsta/ac/bsh/rjc/notices/ParserNotice.java | 106 -- .../rsta/ac/bsh/rjc/parser/ASTFactory.java | 888 --------- .../org/fife/rsta/ac/bsh/rjc/parser/Main.java | 141 -- .../rsta/ac/bsh/tree/AstTreeCellRenderer.java | 44 - .../rsta/ac/bsh/tree/JavaOutlineTree.java | 413 ---- .../fife/rsta/ac/bsh/tree/JavaTreeNode.java | 121 -- .../rsta/ac/bsh/tree/LocalVarTreeNode.java | 53 - .../fife/rsta/ac/bsh/tree/MemberTreeNode.java | 195 -- .../ac/bsh/tree/TypeDeclarationTreeNode.java | 130 -- ...g.fife.rsta.ac.LanguageSupportRegistration | 1 - 115 files changed, 21721 deletions(-) delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/AbstractJavaSourceCompletion.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/ClassCompletion.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/DecoratableIcon.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/DocCommentCompletionProvider.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/FieldCompletion.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/FieldData.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/FieldInfoData.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/IconFactory.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/JarManager.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/JarReader.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/JavaCellRenderer.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/JavaCompletionProvider.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/JavaLanguageRegistration.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/JavaLanguageSupport.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/JavaLinkGenerator.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/JavaParamListCellRenderer.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/JavaParser.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/JavaShorthandCompletion.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/JavaShorthandCompletionCache.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/JavaSourceCompletion.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/JavaTemplateCompletion.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/JavadocUrlHandler.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/LocalVariableCompletion.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/MemberCompletion.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/MethodCompletion.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/MethodData.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/MethodInfoData.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/PackageMapNode.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/PackageNameCompletion.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/SourceCompletionProvider.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/SourceParamChoicesProvider.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/Util.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/buildpath/ClassEnumerationReader.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/buildpath/ClasspathLibraryInfo.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/buildpath/ClasspathSourceLocation.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/buildpath/DirLibraryInfo.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/buildpath/DirSourceLocation.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/buildpath/JarLibraryInfo.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/buildpath/LibraryInfo.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/buildpath/SourceLocation.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/buildpath/ZipSourceLocation.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/AccessFlags.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/ClassFile.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/ExceptionTableEntry.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/FieldInfo.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/Frame.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/MemberInfo.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/MethodInfo.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/Util.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/attributes/AttributeInfo.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/attributes/Code.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/attributes/ConstantValue.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/attributes/Exceptions.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/attributes/Signature.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/attributes/SourceFile.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/attributes/UnsupportedAttribute.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantClassInfo.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantDoubleInfo.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantFieldrefInfo.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantFloatInfo.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantIntegerInfo.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantInterfaceMethodrefInfo.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantInvokeDynamicInfo.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantLongInfo.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantMethodHandleInfo.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantMethodTypeInfo.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantMethodrefInfo.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantNameAndTypeInfo.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantPoolInfo.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantPoolInfoFactory.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantStringInfo.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantTypes.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantUtf8Info.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/ast/ASTNode.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/ast/AbstractASTNode.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/ast/AbstractMember.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/ast/AbstractTypeDeclarationNode.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/ast/CodeBlock.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/ast/CompilationUnit.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/ast/EnumBody.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/ast/EnumDeclaration.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/ast/Field.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/ast/FormalParameter.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/ast/ImportDeclaration.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/ast/LocalVariable.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/ast/Member.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/ast/Method.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/ast/NormalClassDeclaration.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/ast/NormalInterfaceDeclaration.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/ast/Package.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/ast/TypeDeclaration.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/ast/TypeDeclarationContainer.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/lang/Annotation.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/lang/Modifiers.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/lang/Type.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/lang/TypeArgument.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/lang/TypeParameter.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/lang/Variable.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/Offset.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/Scanner.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/SourceCodeScanner.flex delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/SourceCodeScanner.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/Token.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/TokenImpl.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/TokenTypes.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/notices/ParserNotice.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/parser/ASTFactory.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/rjc/parser/Main.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/tree/AstTreeCellRenderer.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/tree/JavaOutlineTree.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/tree/JavaTreeNode.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/tree/LocalVarTreeNode.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/tree/MemberTreeNode.java delete mode 100644 src/main/java/org/fife/rsta/ac/bsh/tree/TypeDeclarationTreeNode.java diff --git a/src/main/java/org/fife/rsta/ac/bsh/AbstractJavaSourceCompletion.java b/src/main/java/org/fife/rsta/ac/bsh/AbstractJavaSourceCompletion.java deleted file mode 100644 index f9d380ba..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/AbstractJavaSourceCompletion.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh; - -import javax.swing.text.JTextComponent; - -import org.fife.ui.autocomplete.BasicCompletion; -import org.fife.ui.autocomplete.Completion; -import org.fife.ui.autocomplete.CompletionProvider; - - -/** - * Base class for Java source completions. - * - * @author Robert Futrell - * @version 1.0 - */ -public abstract class AbstractJavaSourceCompletion extends BasicCompletion - implements JavaSourceCompletion { - - - public AbstractJavaSourceCompletion(CompletionProvider provider, - String replacementText) { - super(provider, replacementText); - } - - - /** - * Overridden to ensure that two completions don't just have the same - * text value (ignoring case), but that they're of the same "type" of - * Completion as well, so, for example, a completion for the - * "String" class won't clash with a completion for a "string" LocalVar. - * - * @param c2 Another completion instance. - * @return How this completion compares to the other one. - */ - @Override - public int compareTo(Completion c2) { - - int rc = -1; - - if (c2==this) { - rc = 0; - } - - else if (c2!=null) { - rc = toString().compareToIgnoreCase(c2.toString()); - if (rc==0) { // Same text value - String clazz1 = getClass().getName(); - clazz1 = clazz1.substring(clazz1.lastIndexOf('.')); - String clazz2 = c2.getClass().getName(); - clazz2 = clazz2.substring(clazz2.lastIndexOf('.')); - rc = clazz1.compareTo(clazz2); - } - } - - return rc; - - } - - - @Override - public String getAlreadyEntered(JTextComponent comp) { - String temp = getProvider().getAlreadyEnteredText(comp); - int lastDot = temp.lastIndexOf('.'); - if (lastDot>-1) { - temp = temp.substring(lastDot+1); - } - return temp; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/ClassCompletion.java b/src/main/java/org/fife/rsta/ac/bsh/ClassCompletion.java deleted file mode 100644 index 22a6d4e8..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/ClassCompletion.java +++ /dev/null @@ -1,232 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh; - -import java.awt.Color; -import java.awt.FontMetrics; -import java.awt.Graphics; -import java.util.Iterator; -import javax.swing.Icon; - -import org.fife.rsta.ac.bsh.buildpath.SourceLocation; -import org.fife.rsta.ac.bsh.classreader.AccessFlags; -import org.fife.rsta.ac.bsh.classreader.ClassFile; -import org.fife.rsta.ac.bsh.rjc.ast.CompilationUnit; -import org.fife.rsta.ac.bsh.rjc.ast.TypeDeclaration; -import org.fife.ui.autocomplete.Completion; -import org.fife.ui.autocomplete.CompletionProvider; - - -/** - * Completion for a Java class, interface or enum. - * - * @author Robert Futrell - * @version 1.0 - */ -class ClassCompletion extends AbstractJavaSourceCompletion { - - private ClassFile cf; - - - public ClassCompletion(CompletionProvider provider, ClassFile cf) { - super(provider, cf.getClassName(false)); - this.cf = cf; - } - - - /* - * Fixed error when comparing classes of the same name, which did not allow - * classes with same name but different packages. - * Thanks to Guilherme Joao Frantz and Jonatas Schuler for the patch! - */ - @Override - public int compareTo(Completion c2) { - if (c2 == this) { - return 0; - } - // Check for classes with same name, but in different packages - else if(c2.toString().equalsIgnoreCase(toString())) { - if (c2 instanceof ClassCompletion) { - ClassCompletion cc2 = (ClassCompletion)c2; - return getClassName(true).compareTo(cc2.getClassName(true)); - } - } - return super.compareTo(c2); - } - - - @Override - public boolean equals(Object obj) { - return (obj instanceof ClassCompletion) && - ((ClassCompletion)obj).getReplacementText().equals(getReplacementText()); - } - - - /** - * Returns the name of the class represented by this completion. - * - * @param fullyQualified Whether the returned name should be fully - * qualified. - * @return The class name. - * @see #getPackageName() - */ - public String getClassName(boolean fullyQualified){ - return cf.getClassName(fullyQualified); - } - - - /** - * {@inheritDoc} - */ - @Override - public Icon getIcon() { - - // TODO: Add functionality to ClassFile to make this simpler. - - boolean isInterface = false; - boolean isPublic = false; - //boolean isProtected = false; - //boolean isPrivate = false; - boolean isDefault = false; - - int access = cf.getAccessFlags(); - if ((access&AccessFlags.ACC_INTERFACE)>0) { - isInterface = true; - } - - else if (org.fife.rsta.ac.bsh.classreader.Util.isPublic(access)) { - isPublic = true; - } -// else if (org.fife.rsta.ac.java.classreader.Util.isProtected(access)) { -// isProtected = true; -// } -// else if (org.fife.rsta.ac.java.classreader.Util.isPrivate(access)) { -// isPrivate = true; -// } - else { - isDefault = true; - } - - IconFactory fact = IconFactory.get(); - String key = null; - - if (isInterface) { - if (isDefault) { - key = IconFactory.DEFAULT_INTERFACE_ICON; - } - else { - key = IconFactory.INTERFACE_ICON; - } - } - else { - if (isDefault) { - key = IconFactory.DEFAULT_CLASS_ICON; - } - else if (isPublic) { - key = IconFactory.CLASS_ICON; - } - } - - return fact.getIcon(key, cf.isDeprecated()); - - } - - - /** - * Returns the package this class or interface is in. - * - * @return The package, or null if it is not in a package. - * @see #getClassName(boolean) - */ - public String getPackageName() { - return cf.getPackageName(); - } - - - @Override - public String getSummary() { - - SourceCompletionProvider scp = (SourceCompletionProvider)getProvider(); - SourceLocation loc = scp.getSourceLocForClass(cf.getClassName(true)); - - if (loc!=null) { - - CompilationUnit cu = Util.getCompilationUnitFromDisk(loc, cf); - if (cu!=null) { - Iterator i=cu.getTypeDeclarationIterator(); - for (; i.hasNext(); ) { - TypeDeclaration td = i.next(); - String typeName = td.getName(); - // Avoid inner classes, etc. - if (typeName.equals(cf.getClassName(false))) { - String summary = td.getDocComment(); - // Be cautious - might be no doc comment (or a bug?) - if (summary!=null && summary.startsWith("/**")) { - return Util.docCommentToHtml(summary); - } - } - } - } - - } - - // Default to the fully-qualified class name. - return cf.getClassName(true); - - } - - - @Override - public String getToolTipText() { - return "class " + getReplacementText(); - } - - - @Override - public int hashCode() { - return getReplacementText().hashCode(); - } - - - public void rendererText(Graphics g, int x, int y, boolean selected) { - - String s = cf.getClassName(false); - g.drawString(s, x, y); - FontMetrics fm = g.getFontMetrics(); - int newX = x + fm.stringWidth(s); - if (cf.isDeprecated()) { - int midY = y + fm.getDescent() - fm.getHeight()/2; - g.drawLine(x, midY, newX, midY); - } - x = newX; - - s = " - "; - g.drawString(s, x, y); - x += fm.stringWidth(s); - - String pkgName = cf.getClassName(true); - int lastIndexOf = pkgName.lastIndexOf('.'); - if (lastIndexOf != -1) { // Class may not be in a package - pkgName = pkgName.substring(0, lastIndexOf); - Color origColor = g.getColor(); - if (!selected) { - g.setColor(Color.GRAY); - } - g.drawString(pkgName, x, y); - if (!selected) { - g.setColor(origColor); - } - } - - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/DecoratableIcon.java b/src/main/java/org/fife/rsta/ac/bsh/DecoratableIcon.java deleted file mode 100644 index 14070370..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/DecoratableIcon.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh; - -import java.awt.Component; -import java.awt.Graphics; -import java.util.ArrayList; -import java.util.List; -import javax.swing.Icon; - - - -/** - * An icon that can have an optional "decorations" icon beside of it. - * - * @author Robert Futrell - * @version 1.0 - */ -public class DecoratableIcon implements Icon { - - /** - * The width of this icon. - */ - private int width; - - /** - * The "main" icon (the icon that is decorated). - */ - private Icon mainIcon; - - /** - * The "decoration" icons. - */ - private List decorations; - - /** - * Whether this icon is for a "deprecated" item. - */ - private boolean deprecated; - - /** - * The width of a decoratable icon (16 + 8 + 8, - 8 for overlap). - */ - private static final int DEFAULT_WIDTH = 24; - - - /** - * Constructor. - * - * @param mainIcon The "main" icon. This cannot be null. - */ - public DecoratableIcon(Icon mainIcon) { - this(DEFAULT_WIDTH, mainIcon); - } - - - /** - * Constructor. - * - * @param width The width for this icon. - * @param mainIcon The "main" icon. This cannot be null. - */ - public DecoratableIcon(int width, Icon mainIcon) { - setMainIcon(mainIcon); - this.width = width; - } - - - /** - * Adds a decoration icon. - * - * @param decoration A new decoration icon. This cannot be - * null. - * @see #setMainIcon(Icon) - */ - public void addDecorationIcon(Icon decoration) { - if (decoration==null) { - throw new IllegalArgumentException("decoration cannot be null"); - } - if (decorations==null) { - decorations = new ArrayList(1); // Usually just 1 - } - decorations.add(decoration); - } - - - /** - * {@inheritDoc} - */ - public int getIconHeight() { - return mainIcon.getIconHeight(); - } - - - /** - * {@inheritDoc} - */ - public int getIconWidth() { - return width; - } - - - /** - * {@inheritDoc} - */ - public void paintIcon(Component c, Graphics g, int x, int y) { - if (deprecated) { - IconFactory.get().getIcon(IconFactory.DEPRECATED_ICON). - paintIcon(c, g, x, y); - } - mainIcon.paintIcon(c, g, x, y); - if (decorations!=null) { - x = x + getIconWidth() - 8; - for (int i=decorations.size()-1; i>=0; i--) { - Icon icon = decorations.get(i); - icon.paintIcon(c, g, x, y); - x -= 8; - } - } - } - - - /** - * Sets whether this icon is for a deprecated item. - * - * @param deprecated Whether this icon is for a deprecated item. - */ - public void setDeprecated(boolean deprecated) { - this.deprecated = deprecated; - } - - - /** - * Sets the main icon. - * - * @param icon The "main" icon. This cannot be null. - * @see #addDecorationIcon(Icon) - */ - public void setMainIcon(Icon icon) { - if (icon==null) { - throw new IllegalArgumentException("icon cannot be null"); - } - this.mainIcon = icon; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/DocCommentCompletionProvider.java b/src/main/java/org/fife/rsta/ac/bsh/DocCommentCompletionProvider.java deleted file mode 100644 index adf8528c..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/DocCommentCompletionProvider.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh; - -import java.awt.Graphics; -import javax.swing.Icon; - -import org.fife.ui.autocomplete.BasicCompletion; -import org.fife.ui.autocomplete.CompletionProvider; -import org.fife.ui.autocomplete.DefaultCompletionProvider; - - -/** - * Completion provider for documentation comments. - * - * @author Robert Futrell - * @version 1.0 - */ -class DocCommentCompletionProvider extends DefaultCompletionProvider { - - - public DocCommentCompletionProvider() { - - // Block tags - addCompletion(new JavadocCompletion(this, "@author")); - addCompletion(new JavadocCompletion(this, "@deprecated")); - addCompletion(new JavadocCompletion(this, "@exception")); - addCompletion(new JavadocCompletion(this, "@param")); - addCompletion(new JavadocCompletion(this, "@return")); - addCompletion(new JavadocCompletion(this, "@see")); - addCompletion(new JavadocCompletion(this, "@serial")); - addCompletion(new JavadocCompletion(this, "@serialData")); - addCompletion(new JavadocCompletion(this, "@serialField")); - addCompletion(new JavadocCompletion(this, "@since")); - addCompletion(new JavadocCompletion(this, "@throws")); - addCompletion(new JavadocCompletion(this, "@version")); - - // Proposed block tags - addCompletion(new JavadocCompletion(this, "@category")); - addCompletion(new JavadocCompletion(this, "@example")); - addCompletion(new JavadocCompletion(this, "@tutorial")); - addCompletion(new JavadocCompletion(this, "@index")); - addCompletion(new JavadocCompletion(this, "@exclude")); - addCompletion(new JavadocCompletion(this, "@todo")); - addCompletion(new JavadocCompletion(this, "@internal")); - addCompletion(new JavadocCompletion(this, "@obsolete")); - addCompletion(new JavadocCompletion(this, "@threadsafety")); - - // Inline tags - addCompletion(new JavadocTemplateCompletion(this, "{@code}", "{@code}", "{@code ${}}${cursor}")); - addCompletion(new JavadocTemplateCompletion(this, "{@docRoot}", "{@docRoot}", "{@docRoot ${}}${cursor}")); - addCompletion(new JavadocTemplateCompletion(this, "{@inheritDoc}", "{@inheritDoc}", "{@inheritDoc ${}}${cursor}")); - addCompletion(new JavadocTemplateCompletion(this, "{@link}", "{@link}", "{@link ${}}${cursor}")); - addCompletion(new JavadocTemplateCompletion(this, "{@linkplain}", "{@linkplain}", "{@linkplain ${}}${cursor}")); - addCompletion(new JavadocTemplateCompletion(this, "{@literal}", "{@literal}", "{@literal ${}}${cursor}")); - addCompletion(new JavadocTemplateCompletion(this, "{@value}", "{@value}", "{@value ${}}${cursor}")); - - // Other common stuff - addCompletion(new JavaShorthandCompletion(this, "null", "null", "null")); - addCompletion(new JavaShorthandCompletion(this, "true", "true", "true")); - addCompletion(new JavaShorthandCompletion(this, "false", "false", "false")); - - setAutoActivationRules(false, "{@"); - - } - - - /** - * {@inheritDoc} - */ - @Override - protected boolean isValidChar(char ch) { - return Character.isLetterOrDigit(ch) || ch=='_' || ch=='@' || - ch=='{' || ch=='}'; - } - - - /** - * A Javadoc completion. - */ - private static class JavadocCompletion extends BasicCompletion - implements JavaSourceCompletion { - - public JavadocCompletion(CompletionProvider provider, - String replacementText) { - super(provider, replacementText); - } - - @Override - public Icon getIcon() { - return IconFactory.get().getIcon(IconFactory.JAVADOC_ITEM_ICON); - } - - public void rendererText(Graphics g, int x, int y, boolean selected) { - g.drawString(getReplacementText(), x, y); - } - - } - - - private static class JavadocTemplateCompletion - extends JavaTemplateCompletion { - - public JavadocTemplateCompletion(CompletionProvider provider, - String inputText, String definitionString, String template) { - super(provider, inputText, definitionString, template); - setIcon(IconFactory.JAVADOC_ITEM_ICON); - } - - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/FieldCompletion.java b/src/main/java/org/fife/rsta/ac/bsh/FieldCompletion.java deleted file mode 100644 index 42b057e9..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/FieldCompletion.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh; - -import java.awt.Graphics; -import javax.swing.Icon; - -import org.fife.rsta.ac.bsh.classreader.FieldInfo; -import org.fife.rsta.ac.bsh.rjc.ast.Field; -import org.fife.rsta.ac.bsh.rjc.lang.Type; -import org.fife.ui.autocomplete.CompletionProvider; - - -/** - * A completion for a Java field. This completion gets its information from - * one of two sources: - * - *
      - *
    • A {@link FieldInfo} instance, which is loaded by parsing a class - * file. This is used when this completion represents a field found - * in a compiled library.
    • - *
    • A {@link Field} instance, which is created when parsing a Java - * source file. This is used when the completion represents a field - * found in uncompiled source, such as the source in an - * RSyntaxTextArea, or in a loose file on disk.
    • - *
    - * - * @author Robert Futrell - * @version 1.0 - */ -class FieldCompletion extends AbstractJavaSourceCompletion - implements MemberCompletion { - - private Data data; - - /** - * The relevance of fields. This allows fields to be "higher" in - * the completion list than other types. - */ - private static final int RELEVANCE = 3; - - - public FieldCompletion(CompletionProvider provider, Field field) { - super(provider, field.getName()); - this.data = new FieldData(field); - setRelevance(RELEVANCE); - } - - - public FieldCompletion(CompletionProvider provider, FieldInfo info) { - super(provider, info.getName()); - this.data = new FieldInfoData(info, (SourceCompletionProvider)provider); - setRelevance(RELEVANCE); - } - - - private FieldCompletion(CompletionProvider provider, String text) { - super(provider, text); - setRelevance(RELEVANCE); - } - - - @Override - public boolean equals(Object obj) { - return (obj instanceof FieldCompletion) && - ((FieldCompletion)obj).getSignature().equals(getSignature()); - } - - - public static FieldCompletion createLengthCompletion( - CompletionProvider provider, final Type type) { - FieldCompletion fc = new FieldCompletion(provider, type.toString()); - fc.data = new Data() { - - public String getEnclosingClassName(boolean fullyQualified) { - return type.getName(fullyQualified); - } - - public String getIcon() { - return IconFactory.FIELD_PUBLIC_ICON; - } - - public String getSignature() { - return "length"; - } - - public String getSummary() { - return null; - } - - public String getType() { - return "int"; - } - - public boolean isConstructor() { - return false; - } - - public boolean isDeprecated() { - return false; - } - - public boolean isAbstract() { - return false; - } - - public boolean isFinal() { - return false; - } - - public boolean isStatic() { - return false; - } - - }; - return fc; - } - - - public String getEnclosingClassName(boolean fullyQualified) { - return data.getEnclosingClassName(fullyQualified); - } - - - @Override - public Icon getIcon() { - return IconFactory.get().getIcon(data); - } - - - public String getSignature() { - return data.getSignature(); - } - - - @Override - public String getSummary() { - - String summary = data.getSummary(); // Could be just the method name - - // If it's the Javadoc for the method... - if (summary!=null && summary.startsWith("/**")) { - summary = org.fife.rsta.ac.bsh.Util.docCommentToHtml(summary); - } - - return summary; - - } - - - public String getType() { - return data.getType(); - } - - - @Override - public int hashCode() { - return getSignature().hashCode(); - } - - - public boolean isDeprecated() { - return data.isDeprecated(); - } - - - public void rendererText(Graphics g, int x, int y, boolean selected) { - MethodCompletion.rendererText(this, g, x, y, selected); - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/FieldData.java b/src/main/java/org/fife/rsta/ac/bsh/FieldData.java deleted file mode 100644 index 78161ac2..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/FieldData.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh; - -import org.fife.rsta.ac.bsh.MemberCompletion.Data; -import org.fife.rsta.ac.bsh.rjc.ast.Field; -import org.fife.rsta.ac.bsh.rjc.ast.TypeDeclaration; -import org.fife.rsta.ac.bsh.rjc.lang.Modifiers; - - -/** - * Metadata about a field as read from a Java source file. This class is - * used by instances of {@link FieldCompletion}. - * - * @author Robert Futrell - * @version 1.0 - */ -class FieldData implements Data { - - private Field field; - - - public FieldData(Field field) { - this.field = field; - } - - - /** - * {@inheritDoc} - */ - public String getEnclosingClassName(boolean fullyQualified) { - // NOTE: This check isn't really necessary, but is here just in case - // there's a bug in the parsing code. - TypeDeclaration td = field.getParentTypeDeclaration(); - if (td==null) { - new Exception("No parent type declaration for: " + getSignature()). - printStackTrace(); - return ""; - } - return td.getName(fullyQualified); - } - - - /** - * {@inheritDoc} - */ - public String getIcon() { - - String key = null; - - Modifiers mod = field.getModifiers(); - if (mod==null) { - key = IconFactory.FIELD_DEFAULT_ICON; - } - else if (mod.isPrivate()) { - key = IconFactory.FIELD_PRIVATE_ICON; - } - else if (mod.isProtected()) { - key = IconFactory.FIELD_PROTECTED_ICON; - } - else if (mod.isPublic()) { - key = IconFactory.FIELD_PUBLIC_ICON; - } - else { - key = IconFactory.FIELD_DEFAULT_ICON; - } - - return key; - - } - - - /** - * {@inheritDoc} - */ - public String getSignature() { - return field.getName(); - } - - - /** - * {@inheritDoc} - */ - public String getSummary() { - String docComment = field.getDocComment(); - return docComment!=null ? docComment : field.toString(); - } - - - /** - * {@inheritDoc} - */ - public String getType() { - return field.getType().toString(); - } - - - public boolean isAbstract() { - return field.getModifiers().isAbstract(); - } - - - /** - * Always returns false, fields cannot be constructors. - * - * @return false always. - */ - public boolean isConstructor() { - return false; - } - - - /** - * {@inheritDoc} - */ - public boolean isDeprecated() { - return field.isDeprecated(); - } - - - public boolean isFinal() { - return field.getModifiers().isFinal(); - } - - - public boolean isStatic() { - return field.getModifiers().isStatic(); - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/FieldInfoData.java b/src/main/java/org/fife/rsta/ac/bsh/FieldInfoData.java deleted file mode 100644 index 6accc76f..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/FieldInfoData.java +++ /dev/null @@ -1,212 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh; - -import java.util.Iterator; - -import org.fife.rsta.ac.bsh.MemberCompletion.Data; -import org.fife.rsta.ac.bsh.buildpath.SourceLocation; -import org.fife.rsta.ac.bsh.classreader.ClassFile; -import org.fife.rsta.ac.bsh.classreader.FieldInfo; -import org.fife.rsta.ac.bsh.classreader.Util; -import org.fife.rsta.ac.bsh.rjc.ast.CompilationUnit; -import org.fife.rsta.ac.bsh.rjc.ast.Field; -import org.fife.rsta.ac.bsh.rjc.ast.Member; -import org.fife.rsta.ac.bsh.rjc.ast.TypeDeclaration; - - -/** - * Metadata about a field as read from a class file. This class is used by - * instances of {@link FieldCompletion}. - * - * @author Robert Futrell - * @version 1.0 - */ -class FieldInfoData implements Data { - - private FieldInfo info; - private SourceCompletionProvider provider; - - - public FieldInfoData(FieldInfo info, SourceCompletionProvider provider) { - this.info = info; - this.provider = provider; - } - - - /** - * {@inheritDoc} - */ - public String getEnclosingClassName(boolean fullyQualified) { - return info.getClassFile().getClassName(fullyQualified); - } - - - /** - * {@inheritDoc} - */ - public String getIcon() { - - String key = null; - int flags = info.getAccessFlags(); - - if (Util.isDefault(flags)) { - key = IconFactory.FIELD_DEFAULT_ICON; - } - else if (Util.isPrivate(flags)) { - key = IconFactory.FIELD_PRIVATE_ICON; - } - else if (Util.isProtected(flags)) { - key = IconFactory.FIELD_PROTECTED_ICON; - } - else if (Util.isPublic(flags)) { - key = IconFactory.FIELD_PUBLIC_ICON; - } - else { - key = IconFactory.FIELD_DEFAULT_ICON; - } - - return key; - - } - - - /** - * {@inheritDoc} - */ - public String getSignature() { - return info.getName(); - } - - - /** - * {@inheritDoc} - */ - public String getSummary() { - - ClassFile cf = info.getClassFile();; - SourceLocation loc = provider.getSourceLocForClass(cf.getClassName(true)); - String summary = null; - - // First, try to parse the Javadoc for this method from the attached - // source. - if (loc!=null) { - summary = getSummaryFromSourceLoc(loc, cf); - } - - // Default to the field name. - if (summary==null) { - summary = info.getName(); - } - return summary; - - } - - - /** - * Scours the source in a location (zip file, directory), looking for a - * particular class's source. If it is found, it is parsed, and the - * Javadoc for this field (if any) is returned. - * - * @param loc The zip file, jar file, or directory to look in. - * @param cf The {@link ClassFile} representing the class of this field. - * @return The summary, or null if the field has no javadoc, - * the class's source was not found, or an IO error occurred. - */ - private String getSummaryFromSourceLoc(SourceLocation loc, ClassFile cf) { - - String summary = null; - CompilationUnit cu = org.fife.rsta.ac.bsh.Util. - getCompilationUnitFromDisk(loc, cf); - - // If the class's source was found and successfully parsed, look for - // this method. - if (cu!=null) { - - Iterator i = cu.getTypeDeclarationIterator(); - while (i.hasNext()) { - - TypeDeclaration td = i.next(); - String typeName = td.getName(); - - // Avoid inner classes, etc. - if (typeName.equals(cf.getClassName(false))) { - - // Locate our field! - Iterator j = td.getMemberIterator(); - while (j.hasNext()) { - Member member = j.next(); - if (member instanceof Field && - member.getName().equals(info.getName())) { - Field f2 = (Field)member; - summary = f2.getDocComment(); - break; - } - } - - } // if (typeName.equals(cf.getClassName(false))) - - } // for (Iterator i=cu.getTypeDeclarationIterator(); i.hasNext(); ) - - } // if (cu!=null) - - return summary; - - } - - - /** - * {@inheritDoc} - */ - public String getType() { - return info.getTypeString(false); - } - - - /** - * Always returns false since fields cannot be abstract. - * - * @return false always. - */ - public boolean isAbstract() { - return false; // Fields cannot be abstract - } - - - /** - * Always returns false, fields cannot be constructors. - * - * @return false always. - */ - public boolean isConstructor() { - return false; - } - - - /** - * {@inheritDoc} - */ - public boolean isDeprecated() { - return info.isDeprecated(); - } - - - public boolean isFinal() { - return info.isFinal(); - } - - - public boolean isStatic() { - return info.isStatic(); - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/IconFactory.java b/src/main/java/org/fife/rsta/ac/bsh/IconFactory.java deleted file mode 100644 index 4560c02b..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/IconFactory.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh; - -import java.net.URL; -import java.util.HashMap; -import java.util.Map; -import javax.swing.Icon; -import javax.swing.ImageIcon; - - - -/** - * Holds icons used by Java auto-completion. - * - * @author Robert Futrell - * @version 1.0 - */ -public class IconFactory { - - public static final String SOURCE_FILE_ICON = "sourceFileIcon"; - public static final String PACKAGE_ICON = "packageIcon"; - public static final String IMPORT_ROOT_ICON = "importRootIcon"; - public static final String IMPORT_ICON = "importIcon"; - public static final String DEFAULT_CLASS_ICON = "defaultClassIcon"; - public static final String DEFAULT_INTERFACE_ICON = "defaultInterfaceIcon"; - public static final String CLASS_ICON = "classIcon"; - public static final String ENUM_ICON = "enumIcon"; - public static final String ENUM_PROTECTED_ICON = "enumProtectedIcon"; - public static final String ENUM_PRIVATE_ICON = "enumPrivateIcon"; - public static final String ENUM_DEFAULT_ICON = "enumDefaultIcon"; - public static final String INNER_CLASS_PUBLIC_ICON = "innerClassPublicIcon"; - public static final String INNER_CLASS_PROTECTED_ICON = "innerClassProtectedIcon"; - public static final String INNER_CLASS_PRIVATE_ICON = "innerClassPrivateIcon"; - public static final String INNER_CLASS_DEFAULT_ICON = "innerClassDefaultIcon"; - public static final String INTERFACE_ICON = "interfaceIcon"; - public static final String JAVADOC_ITEM_ICON = "javadocItemIcon"; - public static final String LOCAL_VARIABLE_ICON = "localVariableIcon"; - public static final String METHOD_PUBLIC_ICON = "methodPublicIcon"; - public static final String METHOD_PROTECTED_ICON = "methodProtectedIcon"; - public static final String METHOD_PRIVATE_ICON = "methodPrivateIcon"; - public static final String METHOD_DEFAULT_ICON = "methodDefaultIcon"; - public static final String TEMPLATE_ICON = "templateIcon"; - public static final String FIELD_PUBLIC_ICON = "fieldPublicIcon"; - public static final String FIELD_PROTECTED_ICON = "fieldProtectedIcon"; - public static final String FIELD_PRIVATE_ICON = "fieldPrivateIcon"; - public static final String FIELD_DEFAULT_ICON = "fieldDefaultIcon"; - - public static final String CONSTRUCTOR_ICON = "constructorIcon"; - public static final String DEPRECATED_ICON = "deprecatedIcon"; - public static final String ABSTRACT_ICON = "abstractIcon"; - public static final String FINAL_ICON = "finalIcon"; - public static final String STATIC_ICON = "staticIcon"; - - private Map iconMap; - - private static final IconFactory INSTANCE = new IconFactory(); - - - private IconFactory() { - - iconMap = new HashMap(); - iconMap.put(SOURCE_FILE_ICON, loadIcon("jcu_obj.gif")); - iconMap.put(PACKAGE_ICON, loadIcon("package_obj.gif")); - iconMap.put(IMPORT_ROOT_ICON, loadIcon("impc_obj.gif")); - iconMap.put(IMPORT_ICON, loadIcon("imp_obj.gif")); - iconMap.put(DEFAULT_CLASS_ICON, loadIcon("class_default_obj.gif")); - iconMap.put(DEFAULT_INTERFACE_ICON, loadIcon("int_default_obj.gif")); - iconMap.put(CLASS_ICON, loadIcon("class_obj.gif")); - iconMap.put(ENUM_ICON, loadIcon("enum_obj.gif")); - iconMap.put(ENUM_PROTECTED_ICON, loadIcon("enum_protected_obj.gif")); - iconMap.put(ENUM_PRIVATE_ICON, loadIcon("enum_private_obj.gif")); - iconMap.put(ENUM_DEFAULT_ICON, loadIcon("enum_default_obj.gif")); - iconMap.put(INNER_CLASS_PUBLIC_ICON, loadIcon("innerclass_public_obj.gif")); - iconMap.put(INNER_CLASS_PROTECTED_ICON, loadIcon("innerclass_protected_obj.gif")); - iconMap.put(INNER_CLASS_PRIVATE_ICON, loadIcon("innerclass_private_obj.gif")); - iconMap.put(INNER_CLASS_DEFAULT_ICON, loadIcon("innerclass_default_obj.gif")); - iconMap.put(INTERFACE_ICON, loadIcon("int_obj.gif")); - iconMap.put(JAVADOC_ITEM_ICON, loadIcon("jdoc_tag_obj.gif")); - iconMap.put(LOCAL_VARIABLE_ICON, loadIcon("localvariable_obj.gif")); - iconMap.put(METHOD_PUBLIC_ICON, loadIcon("methpub_obj.gif")); - iconMap.put(METHOD_PROTECTED_ICON, loadIcon("methpro_obj.gif")); - iconMap.put(METHOD_PRIVATE_ICON, loadIcon("methpri_obj.gif")); - iconMap.put(METHOD_DEFAULT_ICON, loadIcon("methdef_obj.gif")); - iconMap.put(TEMPLATE_ICON, loadIcon("template_obj.gif")); - iconMap.put(FIELD_PUBLIC_ICON, loadIcon("field_public_obj.gif")); - iconMap.put(FIELD_PROTECTED_ICON, loadIcon("field_protected_obj.gif")); - iconMap.put(FIELD_PRIVATE_ICON, loadIcon("field_private_obj.gif")); - iconMap.put(FIELD_DEFAULT_ICON, loadIcon("field_default_obj.gif")); - - iconMap.put(CONSTRUCTOR_ICON, loadIcon("constr_ovr.gif")); - iconMap.put(DEPRECATED_ICON, loadIcon("deprecated.gif")); - iconMap.put(ABSTRACT_ICON, loadIcon("abstract_co.gif")); - iconMap.put(FINAL_ICON, loadIcon("final_co.gif")); - iconMap.put(STATIC_ICON, loadIcon("static_co.gif")); - - } - - - public static IconFactory get() { - return INSTANCE; - } - - - public Icon getIcon(String key) { - return getIcon(key, false); - } - - - public Icon getIcon(String key, boolean deprecated) { - Icon icon = iconMap.get(key); - if (deprecated) { // TODO: Optimize me - DecoratableIcon di = new DecoratableIcon(16, icon); - di.setDeprecated(deprecated); - icon = di; - } - return icon; - } - - - public Icon getIcon(IconData data) { - // TODO: Optimize me - DecoratableIcon icon = new DecoratableIcon(16, getIcon(data.getIcon())); - icon.setDeprecated(data.isDeprecated()); - if (data.isAbstract()) { - icon.addDecorationIcon(getIcon(ABSTRACT_ICON)); - } - if (data.isStatic()) { - icon.addDecorationIcon(getIcon(STATIC_ICON)); - } - if (data.isFinal()) { - icon.addDecorationIcon(getIcon(FINAL_ICON)); - } - return icon; - } - - - private Icon loadIcon(String name) { - URL res = getClass().getResource("img/" + name); - if (res==null) { - // IllegalArgumentException is what would be thrown if res - // was null anyway, we're just giving the actual arg name to - // make the message more descriptive - throw new IllegalArgumentException("icon not found: img/" + name); - } - return new ImageIcon(res); - } - - - public static interface IconData { - - /** - * Returns the main icon to use when rendering this member's completion. - * This icon will be decorated appropriately based on whether it is - * abstract, deprecated, final, static, or any of the above. - * - * @return The icon to use. - */ - public String getIcon(); - - public boolean isAbstract(); - - public boolean isDeprecated(); - - public boolean isFinal(); - - public boolean isStatic(); - - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/JarManager.java b/src/main/java/org/fife/rsta/ac/bsh/JarManager.java deleted file mode 100644 index 532e1563..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/JarManager.java +++ /dev/null @@ -1,433 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import org.fife.rsta.ac.bsh.buildpath.JarLibraryInfo; -import org.fife.rsta.ac.bsh.buildpath.LibraryInfo; -import org.fife.rsta.ac.bsh.buildpath.SourceLocation; -import org.fife.rsta.ac.bsh.classreader.ClassFile; -import org.fife.rsta.ac.bsh.rjc.ast.ImportDeclaration; -import org.fife.ui.autocomplete.Completion; -import org.fife.ui.autocomplete.CompletionProvider; - - -/** - * Manages a list of jars and gets completions from them. This can be shared - * amongst multiple {@link JavaCompletionProvider} instances. - * - * @author Robert Futrell - * @version 1.0 - */ -public class JarManager { - - /** - * Locations of class files to get completions from. - */ - private List classFileSources; - - /** - * Whether to check datestamps on jars/directories when completion - * information is requested. - */ - private static boolean checkModified; - - - /** - * Constructor. - */ - public JarManager() { - classFileSources = new ArrayList(); - setCheckModifiedDatestamps(true); - } - - - /** - * Adds completions matching the specified text to a list. - * - * @param p The parent completion provider. - * @param text The text to match. - * @param addTo The list to add completion choices to. - */ - public void addCompletions(CompletionProvider p, String text, - Set addTo) { -/* - * The commented-out code below is probably replaced by the rest of the code - * in this method... -TODO: Verify me!!! - * - // Add any completions matching the text for each jar we know about - String[] pkgNames = Util.splitOnChar(text, '.'); - for (int i=0; i-1) { - String[] pkgNames = Util.splitOnChar(text, '.'); - for (int i=0; i classFiles = jar. - getClassesWithNamesStartingWith(lowerCaseText); - if (classFiles!=null) { - for (ClassFile cf : classFiles) { - if (org.fife.rsta.ac.bsh.classreader.Util.isPublic(cf.getAccessFlags())) { - addTo.add(new ClassCompletion(p, cf)); - } - } - } - } - } - - } - - - /** - * Adds a jar to read from. This is a convenience method for folks only - * reading classes from jar files. - * - * @param jarFile The jar to add. This cannot be null. - * @return Whether this jar was added (e.g. it wasn't already loaded, or - * it has a new source path). - * @throws IOException If an IO error occurs. - * @see #addClassFileSource(LibraryInfo) - * @see #addCurrentJreClassFileSource() - * @see #getClassFileSources() - * @see #removeClassFileSource(File) - */ - public boolean addClassFileSource(File jarFile) throws IOException { - if (jarFile==null) { - throw new IllegalArgumentException("jarFile cannot be null"); - } - return addClassFileSource(new JarLibraryInfo(jarFile)); - } - - - /** - * Adds a class file source to read from. - * - * @param info The source to add. If this is null, then - * the current JVM's main JRE jar (rt.jar, or classes.jar on OS X) - * will be added. If this source has already been added, adding it - * again will do nothing (except possibly update its attached source - * location). - * @return Whether this source was added (e.g. it wasn't already loaded, or - * it has a new source path). - * @throws IOException If an IO error occurs. - * @see #addClassFileSource(File) - * @see #addCurrentJreClassFileSource() - * @see #getClassFileSources() - * @see #removeClassFileSource(LibraryInfo) - */ - public boolean addClassFileSource(LibraryInfo info) throws IOException { - - if (info==null) { - throw new IllegalArgumentException("info cannot be null"); - } - - // First see if this jar is already on the "build path." - for (int i=0; inull if there are none. - */ - public List getClassesWithUnqualifiedName(String name, - List importDeclarations) { - - // Might be more than one class/interface/enum with the same name. - List result = null; - - // Loop through all of our imports. - for (ImportDeclaration idec : importDeclarations) { - - // Static imports are for fields/methods, not classes - if (!idec.isStatic()) { - - // Wildcard => See if package contains a class with this name - if (idec.isWildcard()) { - - String qualified = idec.getName(); - qualified = qualified.substring(0, qualified.indexOf('*')); - qualified += name; - ClassFile entry = getClassEntry(qualified); - if (entry!=null) { - if (result==null) { - result = new ArrayList(1); // Usually small - } - result.add(entry); - } - - } - - // Not wildcard => fully-qualified class/interface name - else { - String name2 = idec.getName(); - String unqualifiedName2 = name2.substring(name2.lastIndexOf('.')+1); - if (unqualifiedName2.equals(name)) { - ClassFile entry = getClassEntry(name2); - if (entry!=null) { // Should always be true - if (result==null) { - result = new ArrayList(1); // Usually small - } - result.add(entry); - } - else { - System.err.println("ERROR: Class not found! - " + name2); - } - } - } - - } - - } - - // Also check java.lang - String qualified = "java.lang." + name; - ClassFile entry = getClassEntry(qualified); - if (entry!=null) { - if (result==null) { - result = new ArrayList(1); // Usually small - } - result.add(entry); - } - - return result; - - } - - - /** - * - * @param pkgName A package name. - * @return A list of all classes in that package. - */ - public List getClassesInPackage(String pkgName, boolean inPkg) { - - List list = new ArrayList(); - String[] pkgs = Util.splitOnChar(pkgName, '.'); - - for (int i=0; iLibraryInfo in this list will have no effect on - * this completion provider; in order to do that, you must re-add - * the jar via {@link #addClassFileSource(LibraryInfo)}. If there - * are no jars on the "build path," this will be an empty list. - * @see #addClassFileSource(LibraryInfo) - */ - public List getClassFileSources() { - List jarList = - new ArrayList(classFileSources.size()); - for (JarReader reader : classFileSources) { - jarList.add(reader.getLibraryInfo()); // Already cloned - } - return jarList; - } - - -public SourceLocation getSourceLocForClass(String className) { - SourceLocation sourceLoc = null; - for (int i=0; ifalse - * if the jar was not on the build path. - * @see #removeClassFileSource(LibraryInfo) - * @see #addClassFileSource(LibraryInfo) - * @see #getClassFileSources() - */ - public boolean removeClassFileSource(File jar) { - return removeClassFileSource(new JarLibraryInfo(jar)); - } - - - /** - * Removes a class file source from the "build path." - * - * @param toRemove The source to remove. - * @return Whether source jar was removed. This will be false - * if the source was not on the build path. - * @see #removeClassFileSource(File) - * @see #addClassFileSource(LibraryInfo) - * @see #getClassFileSources() - */ - public boolean removeClassFileSource(LibraryInfo toRemove) { - for (Iterator i=classFileSources.iterator(); i.hasNext(); ) { - JarReader reader = i.next(); - LibraryInfo info = reader.getLibraryInfo(); - if (info.equals(toRemove)) { - i.remove(); - return true; - } - } - return false; - } - - - /** - * Sets whether the "last modified" time stamp on jars and class - * directories should be checked whenever completions are requested, and - * if the jar/directory has been modified since the last time, reload any - * cached class file data. This allows for code completion to update - * whenever dependencies are rebuilt, but has the side effect of increased - * file I/O. By default this option is enabled; if you somehow find the - * file I/O to be a bottleneck (perhaps accessing jars over a slow NFS - * mount), you can disable this option. - * - * @param check Whether to check if any jars/directories have been - * modified since the last access, and clear any cached completion - * information if so. - * @see #getCheckModifiedDatestamps() - */ - public static void setCheckModifiedDatestamps(boolean check) { - checkModified = check; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/JarReader.java b/src/main/java/org/fife/rsta/ac/bsh/JarReader.java deleted file mode 100644 index 679aa9ad..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/JarReader.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -import org.fife.rsta.ac.bsh.buildpath.LibraryInfo; -import org.fife.rsta.ac.bsh.classreader.ClassFile; -import org.fife.ui.autocomplete.Completion; -import org.fife.ui.autocomplete.CompletionProvider; - - -/** - * Reads entries from a source of class files, such as a jar or a "bin/" - * directory. This class acts as an intermediary between a raw - * LibraryInfo and the higher level Java completion classes. - * It caches information about classes and refreshes that cache when - * appropriate. - * - * @author Robert Futrell - * @version 1.0 - */ -class JarReader { - - /** - * Information about the jar or directory we're reading classes from. - */ - private LibraryInfo info; - - /** - * Data structure that caches {@link ClassFile}s. - */ - private PackageMapNode packageMap; - - private long lastModified; - - - /** - * Constructor. - * - * @param info The jar file to read from. This cannot be null. - * @throws IOException If an IO error occurs reading from the jar file. - */ - public JarReader(LibraryInfo info) throws IOException { - this.info = info; - packageMap = new PackageMapNode(); - loadCompletions(); - } - - - /** - * Gets the completions in this jar that match a given string. - * - * @param provider The parent completion provider. - * @param pkgNames The text to match, split into tokens around the - * '.' character. This should be (the start of) a - * fully-qualified class, interface, or enum name. - * @param addTo The list to add completion choices to. - */ - public void addCompletions(CompletionProvider provider, String[] pkgNames, - Set addTo) { - checkLastModified(); - packageMap.addCompletions(info, provider, pkgNames, addTo); - } - - - /** - * Checks whether the jar or class file directory has been modified since - * the last use of this reader. If it has, then any cached - * ClassFiles are cleared, in case any classes have been - * updated. - */ - private void checkLastModified() { - long newLastModified = info.getLastModified(); - if (newLastModified!=0 && newLastModified!=lastModified) { - int count = 0; - count = packageMap.clearClassFiles(); - System.out.println("DEBUG: Cleared " + count + " cached ClassFiles"); - lastModified = newLastModified; - } - } - - - public boolean containsClass(String className) { - return packageMap.containsClass(className); - } - - - public boolean containsPackage(String pkgName) { - return packageMap.containsPackage(pkgName); - } - - - public ClassFile getClassEntry(String[] items) { - return packageMap.getClassEntry(info, items); - } - - - public void getClassesInPackage(List addTo, String[] pkgs, - boolean inPkg) { - packageMap.getClassesInPackage(info, addTo, pkgs, inPkg); - } - - - /** - * Looks through all classes in this jar or directory, trying to find any - * whose unqualified names start with a given prefix. - * - * @param prefix The prefix of the class names. Case is ignored on this - * parameter. - * @return A list of {@link ClassFile}s representing classes in this - * jar or directory whose unqualified names start with the prefix. - * This will never be null, but may of course be - * empty. - */ - public List getClassesWithNamesStartingWith(String prefix) { - List res = new ArrayList(); - String currentPkg = ""; // Don't use null; we're appending to it - packageMap.getClassesWithNamesStartingWith(info, prefix, currentPkg, - res); - return res; - } - - - /** - * Returns the physical file on disk.

    - * - * Modifying the returned object will not have any effect on - * code completion; e.g. changing the source location will not have any - * effect. - * - * @return The info. - */ - public LibraryInfo getLibraryInfo() { - return (LibraryInfo)info.clone(); - } - - - private void loadCompletions() throws IOException { - packageMap = info.createPackageMap(); - lastModified = info.getLastModified(); - } - - - @Override - public String toString() { - return "[JarReader: " + getLibraryInfo() + "]"; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/JavaCellRenderer.java b/src/main/java/org/fife/rsta/ac/bsh/JavaCellRenderer.java deleted file mode 100644 index 58ffc5cf..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/JavaCellRenderer.java +++ /dev/null @@ -1,210 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh; - -import java.awt.Color; -import java.awt.Component; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.RenderingHints; -import java.util.Map; -import javax.swing.DefaultListCellRenderer; -import javax.swing.JList; - -import org.fife.ui.autocomplete.Completion; -import org.fife.ui.rsyntaxtextarea.RSyntaxUtilities; - - -/** - * Cell renderer for Java auto-completion. This renderer attempts to be - * fast due to the possibility of many (100+) auto-completions dynamically - * generated for large Java classes. Using Swing's HTML support is simply - * too slow (see {@link CompletionCellRenderer}).

    - * - * The color scheme for this renderer mimics that found in Eclipse. - * - * @author Robert Futrell - * @version 1.0 - */ -public class JavaCellRenderer extends DefaultListCellRenderer { - - private JList list; - private boolean selected; - private boolean evenRow; - private JavaSourceCompletion jsc; - - /** - * The alternating background color, or null for none. - */ - private static Color altBG; - - /** - * This is used instead of jsc for "incomplete" stuff, like classes, - * interfaces, etc. read from jars (don't yet read the class in, for - * example). - */ - private Completion nonJavaCompletion; - - /** - * Whether to not display extra info (type, etc.)in completion text, just - * the completion's name. The default is false. - */ - private boolean simpleText; - - - /** - * Returns the background color to use on alternating lines. - * - * @return The alternate background color. If this is null, - * alternating colors are not used. - * @see #setAlternateBackground(Color) - */ - public static Color getAlternateBackground() { - return altBG; - } - - - /** - * Returns the renderer. - * - * @param list The list of choices being rendered. - * @param value The {@link Completion} being rendered. - * @param index The index into list being rendered. - * @param selected Whether the item is selected. - * @param hasFocus Whether the item has focus. - */ - @Override - public Component getListCellRendererComponent(JList list, Object value, - int index, boolean selected, boolean hasFocus) { - - super.getListCellRendererComponent(list, value, index, selected, hasFocus); - - setText("Foobar"); // Just something to give it proper height - this.list = list; - this.selected = selected; - - if (value instanceof JavaSourceCompletion) { - jsc = (JavaSourceCompletion)value; - nonJavaCompletion = null; - setIcon(jsc.getIcon()); - } - else { - jsc = null; - nonJavaCompletion = (Completion)value; - setIcon(nonJavaCompletion.getIcon()); - } - - evenRow = (index&1) == 0; - if (altBG!=null && evenRow && !selected) { - setBackground(altBG); - } - - return this; - - } - - - @Override - protected void paintComponent(Graphics g) { - - // Set up rendering hints to look as close to native as possible - Graphics2D g2d = (Graphics2D)g; - Object old = null; - - // First, try to use the rendering hint set that is "native". - Map hints = RSyntaxUtilities.getDesktopAntiAliasHints(); - if (hints!=null) { - old = g2d.getRenderingHints(); - g2d.addRenderingHints(hints); - } - // If a "native" set isn't found, just turn on standard text AA. - else { - old = g2d.getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING); - g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, - RenderingHints.VALUE_TEXT_ANTIALIAS_ON); - } - -// if (jsc!=null) { -// setText(null); // Stop "Foobar" from being painted -// } - - // We never paint "selection" around the icon, to imitate Eclipse - final int iconW = 18; - int h = getHeight(); - if (!selected) { - g.setColor(getBackground()); - g.fillRect(0,0, getWidth(),h); - } - else { - g.setColor(altBG!=null && evenRow ? altBG : list.getBackground()); - g.fillRect(0,0, iconW,h); - g.setColor(getBackground()); // Selection color - g.fillRect(iconW, 0, getWidth()-iconW, h); - } - if (getIcon()!=null) { - int y = (h - getIcon().getIconHeight())/2; - getIcon().paintIcon(this, g, 0, y); - } - - int x = getX() + iconW + 2; - g.setColor(selected ? list.getSelectionForeground() : - list.getForeground()); - if (jsc!=null && !simpleText) { - jsc.rendererText(g, x, g.getFontMetrics().getHeight(), selected); - } - else { - Completion c = jsc!=null ? jsc : nonJavaCompletion; - if (c!=null) { - g.drawString(c.toString(), x, g.getFontMetrics().getHeight()); - } - } - - // Restore rendering hints appropriately. - if (hints!=null) { - if (old instanceof Map) { - g2d.addRenderingHints((Map)old); - } - else { - g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, old); - } - } - else { - g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, old); - } - - } - - - /** - * Sets the background color to use on alternating lines. - * - * @param altBG The new alternate background color. If this is - * null, alternating lines will not use different - * background colors. - * @see #getAlternateBackground() - */ - public static void setAlternateBackground(Color altBG) { - JavaCellRenderer.altBG = altBG; - } - - - /** - * Sets whether to display "simple" text about the completion - just the - * name, no type information, etc. The default value is false. - * - * @param simple Whether to display "simple" text about the completion. - */ - public void setSimpleText(boolean simple) { - simpleText = simple; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/JavaCompletionProvider.java b/src/main/java/org/fife/rsta/ac/bsh/JavaCompletionProvider.java deleted file mode 100644 index 7cdcf4f9..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/JavaCompletionProvider.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh; - -import java.awt.Point; -import java.io.File; -import java.io.IOException; -import java.util.List; -import javax.swing.text.JTextComponent; - -import org.fife.rsta.ac.ShorthandCompletionCache; -import org.fife.rsta.ac.bsh.buildpath.LibraryInfo; -import org.fife.rsta.ac.bsh.rjc.ast.CompilationUnit; -import org.fife.ui.autocomplete.AbstractCompletionProvider; -import org.fife.ui.autocomplete.Completion; -import org.fife.ui.autocomplete.DefaultCompletionProvider; -import org.fife.ui.autocomplete.LanguageAwareCompletionProvider; -import org.fife.ui.autocomplete.ParameterizedCompletion; - - -/** - * Completion provider for the Java programming language. - * - * @author Robert Futrell - * @version 1.0 - */ -public class JavaCompletionProvider extends LanguageAwareCompletionProvider { - - /** - * The provider used for source code, kept here since it's used so much. - */ - private SourceCompletionProvider sourceProvider; - - private CompilationUnit cu; - - - /** - * Constructor. - */ - public JavaCompletionProvider() { - this(null); - } - - - /** - * Constructor. - * - * @param jarManager The jar manager to use when looking up completion - * choices. This can be passed in to share a single jar manager - * across multiple RSyntaxTextAreas. This may also be - * null, in which case this completion provider will - * have a unique JarManager. - */ - public JavaCompletionProvider(JarManager jarManager) { - - super(new SourceCompletionProvider(jarManager)); - this.sourceProvider = (SourceCompletionProvider) - getDefaultCompletionProvider(); - sourceProvider.setJavaProvider(this); - setShorthandCompletionCache(new JavaShorthandCompletionCache( - sourceProvider, new DefaultCompletionProvider())); - setDocCommentCompletionProvider(new DocCommentCompletionProvider()); - - } - - - /** - * Adds a jar to the "build path." - * - * @param info The jar to add. If this is null, then - * the current JVM's main JRE jar (rt.jar, or classes.jar on OS X) - * will be added. If this jar has already been added, adding it - * again will do nothing (except possibly update its attached source - * location). - * @throws IOException If an IO error occurs. - * @see #removeJar(File) - * @see #getJars() - */ - public void addJar(LibraryInfo info) throws IOException { - sourceProvider.addJar(info); - } - - - /** - * Removes all jars from the "build path." - * - * @see #removeJar(File) - * @see #addJar(LibraryInfo) - * @see #getJars() - */ - public void clearJars() { - sourceProvider.clearJars(); - } - - - /** - * Defers to the source-analyzing completion provider. - * - * @return The already entered text. - */ - @Override - public String getAlreadyEnteredText(JTextComponent comp) { - return sourceProvider.getAlreadyEnteredText(comp); - } - - - public synchronized CompilationUnit getCompilationUnit() { - return cu; - } - - - /** - * {@inheritDoc} - */ - @Override - public List getCompletionsAt(JTextComponent tc, Point p) { - return sourceProvider.getCompletionsAt(tc, p); - } - - - /** - * Returns the jars on the "build path." - * - * @return A list of {@link LibraryInfo}s. Modifying a - * LibraryInfo in this list will have no effect on - * this completion provider; in order to do that, you must re-add - * the jar via {@link #addJar(LibraryInfo)}. If there are - * no jars on the "build path," this will be an empty list. - * @see #addJar(LibraryInfo) - */ - public List getJars() { - return sourceProvider.getJars(); - } - - - /** - * {@inheritDoc} - */ - @Override - public List getParameterizedCompletions( - JTextComponent tc) { - return null; - } - - - /** - * Removes a jar from the "build path." - * - * @param jar The jar to remove. - * @return Whether the jar was removed. This will be false - * if the jar was not on the build path. - * @see #addJar(LibraryInfo) - */ - public boolean removeJar(File jar) { - return sourceProvider.removeJar(jar); - } - - - private void setCommentCompletions(ShorthandCompletionCache shorthandCache) { - AbstractCompletionProvider provider = shorthandCache.getCommentProvider(); - if(provider != null) { - for (Completion c : shorthandCache.getCommentCompletions()) { - provider.addCompletion(c); - } - setCommentCompletionProvider(provider); - } - } - - - public synchronized void setCompilationUnit(CompilationUnit cu) { - this.cu = cu; - } - - - /** - * Set short hand completion cache (template and comment completions) - */ - public void setShorthandCompletionCache(ShorthandCompletionCache cache) { - sourceProvider.setShorthandCache(cache); - //reset comment completions too - setCommentCompletions(cache); - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/JavaLanguageRegistration.java b/src/main/java/org/fife/rsta/ac/bsh/JavaLanguageRegistration.java deleted file mode 100644 index 6fa2bf84..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/JavaLanguageRegistration.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package org.fife.rsta.ac.bsh; - -import org.fife.rsta.ac.LanguageSupportRegistration; -import org.fife.ui.rsyntaxtextarea.modes.BshTokenRegistration; - -/** - * - * @author matta - */ -public class JavaLanguageRegistration implements LanguageSupportRegistration { - - @Override - public String getLanguage() { - return BshTokenRegistration.SYNTAX_STYLE; - } - - @Override - public String getLanguageSupportType() { - return JavaLanguageSupport.class.getName(); - } - -} diff --git a/src/main/java/org/fife/rsta/ac/bsh/JavaLanguageSupport.java b/src/main/java/org/fife/rsta/ac/bsh/JavaLanguageSupport.java deleted file mode 100644 index 06b087ae..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/JavaLanguageSupport.java +++ /dev/null @@ -1,594 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh; - -import java.awt.Point; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.InputEvent; -import java.awt.event.KeyEvent; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import javax.swing.ActionMap; -import javax.swing.InputMap; -import javax.swing.KeyStroke; -import javax.swing.Timer; -import javax.swing.event.CaretEvent; -import javax.swing.event.CaretListener; -import javax.swing.text.BadLocationException; -import javax.swing.text.Document; -import javax.swing.text.Element; - -import org.fife.rsta.ac.AbstractLanguageSupport; -import org.fife.rsta.ac.GoToMemberAction; -import org.fife.rsta.ac.bsh.rjc.ast.CompilationUnit; -import org.fife.rsta.ac.bsh.rjc.ast.ImportDeclaration; -import org.fife.rsta.ac.bsh.rjc.ast.Package; -import org.fife.rsta.ac.bsh.tree.JavaOutlineTree; -import org.fife.ui.autocomplete.AutoCompletion; -import org.fife.ui.autocomplete.Completion; -import org.fife.ui.rsyntaxtextarea.RSyntaxDocument; -import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; -import org.fife.ui.rsyntaxtextarea.SyntaxConstants; - -/** - * Language support for Java. - * - * @author Robert Futrell - * @version 1.0 - * @see JavaOutlineTree - */ -public class JavaLanguageSupport extends AbstractLanguageSupport { - - /** - * Maps JavaParsers to Info instances about them. - */ - private Map parserToInfoMap; - - /** - * The shared jar manager to use with all {@link JavaCompletionProvider}s, - * or null if each one should have a unique jar manager. - */ - private JarManager jarManager; - - /** - * Client property installed on text areas that points to a listener. - */ - private static final String PROPERTY_LISTENER - = "org.fife.rsta.ac.bsh.JavaLanguageSupport.Listener"; - - /** - * Constructor. - */ - public JavaLanguageSupport() { - parserToInfoMap = new HashMap(); - jarManager = new JarManager(); - setAutoActivationEnabled(true); - setParameterAssistanceEnabled(true); - setShowDescWindow(true); - } - - /** - * Returns the completion provider running on a text area with this Java - * language support installed. - * - * @param textArea The text area. - * @return The completion provider. This will be null if the - * text area does not have this JavaLanguageSupport - * installed. - */ - public JavaCompletionProvider getCompletionProvider( - RSyntaxTextArea textArea) { - AutoCompletion ac = getAutoCompletionFor(textArea); - return (JavaCompletionProvider) ac.getCompletionProvider(); - } - - /** - * Returns the shared jar manager instance. NOTE: This method will be - * removed over time, as the Java support becomes more robust! - * - * @return The shared jar manager. - */ - public JarManager getJarManager() { - return jarManager; - } - - /** - * Returns the Java parser running on a text area with this Java language - * support installed. - * - * @param textArea The text area. - * @return The Java parser. This will be null if the text area - * does not have this JavaLanguageSupport installed. - */ - public JavaParser getParser(RSyntaxTextArea textArea) { - // Could be a parser for another language. - Object parser = textArea.getClientProperty(PROPERTY_LANGUAGE_PARSER); - if (parser instanceof JavaParser) { - return (JavaParser) parser; - } - return null; - } - - /** - * {@inheritDoc} - */ - public void install(RSyntaxTextArea textArea) { - - JavaCompletionProvider p = new JavaCompletionProvider(jarManager); - // Can't use createAutoCompletion(), as Java's is "special." - AutoCompletion ac = new JavaAutoCompletion(p, textArea); - ac.setListCellRenderer(new JavaCellRenderer()); - ac.setAutoCompleteEnabled(isAutoCompleteEnabled()); - ac.setAutoActivationEnabled(isAutoActivationEnabled()); - ac.setAutoActivationDelay(getAutoActivationDelay()); - ac.setExternalURLHandler(new JavadocUrlHandler()); - ac.setParameterAssistanceEnabled(isParameterAssistanceEnabled()); - ac.setParamChoicesRenderer(new JavaParamListCellRenderer()); - ac.setShowDescWindow(getShowDescWindow()); - ac.install(textArea); - installImpl(textArea, ac); - - textArea.setToolTipSupplier(p); - - Listener listener = new Listener(textArea); - textArea.putClientProperty(PROPERTY_LISTENER, listener); - - JavaParser parser = new JavaParser(textArea); - textArea.putClientProperty(PROPERTY_LANGUAGE_PARSER, parser); - textArea.addParser(parser); - textArea.setToolTipSupplier(p); - - Info info = new Info(textArea, p, parser); - parserToInfoMap.put(parser, info); - - installKeyboardShortcuts(textArea); - - textArea.setLinkGenerator(new JavaLinkGenerator(this)); - - } - - /** - * Installs extra keyboard shortcuts supported by this language support. - * - * @param textArea The text area to install the shortcuts into. - */ - private void installKeyboardShortcuts(RSyntaxTextArea textArea) { - - InputMap im = textArea.getInputMap(); - ActionMap am = textArea.getActionMap(); - int c = textArea.getToolkit().getMenuShortcutKeyMask(); - int shift = InputEvent.SHIFT_MASK; - - im.put(KeyStroke.getKeyStroke(KeyEvent.VK_O, c | shift), "GoToType"); - am.put("GoToType", new GoToMemberAction(JavaOutlineTree.class)); - - } - - /** - * {@inheritDoc} - */ - public void uninstall(RSyntaxTextArea textArea) { - - uninstallImpl(textArea); - - JavaParser parser = getParser(textArea); - Info info = parserToInfoMap.remove(parser); - if (info != null) { // Should always be true - parser.removePropertyChangeListener( - JavaParser.PROPERTY_COMPILATION_UNIT, info); - } - textArea.removeParser(parser); - textArea.putClientProperty(PROPERTY_LANGUAGE_PARSER, null); - textArea.setToolTipSupplier(null); - - Object listener = textArea.getClientProperty(PROPERTY_LISTENER); - if (listener instanceof Listener) { // Should always be true - ((Listener) listener).uninstall(); - textArea.putClientProperty(PROPERTY_LISTENER, null); - } - - uninstallKeyboardShortcuts(textArea); - textArea.setLinkGenerator(null); - - } - - /** - * Uninstalls any keyboard shortcuts specific to this language support. - * - * @param textArea The text area to uninstall the actions from. - */ - private void uninstallKeyboardShortcuts(RSyntaxTextArea textArea) { - - InputMap im = textArea.getInputMap(); - ActionMap am = textArea.getActionMap(); - int c = textArea.getToolkit().getMenuShortcutKeyMask(); - int shift = InputEvent.SHIFT_MASK; - - im.remove(KeyStroke.getKeyStroke(KeyEvent.VK_O, c | shift)); - am.remove("GoToType"); - - } - - /** - * Information about an import statement to add and where it should be - * added. This is used internally when a class completion is inserted, and - * it needs an import statement added to the source. - */ - private static class ImportToAddInfo { - - public int offs; - public String text; - - public ImportToAddInfo(int offset, String text) { - this.offs = offset; - this.text = text; - } - - } - - /** - * Manages information about the parsing/auto-completion for a single text - * area. Unlike many simpler language supports, - * JavaLanguageSupport cannot share any information amongst - * instances of RSyntaxTextArea. - */ - private static class Info implements PropertyChangeListener { - - public JavaCompletionProvider provider; - //public JavaParser parser; - - public Info(RSyntaxTextArea textArea, JavaCompletionProvider provider, - JavaParser parser) { - this.provider = provider; - //this.parser = parser; - parser.addPropertyChangeListener( - JavaParser.PROPERTY_COMPILATION_UNIT, this); - } - - /** - * Called when a text area is re-parsed. - * - * @param e The event. - */ - public void propertyChange(PropertyChangeEvent e) { - - String name = e.getPropertyName(); - - if (JavaParser.PROPERTY_COMPILATION_UNIT.equals(name)) { - CompilationUnit cu = (CompilationUnit) e.getNewValue(); -// structureTree.update(file, cu); -// updateTable(); - provider.setCompilationUnit(cu); - } - - } - - } - - /** - * A hack of AutoCompletion that forces the JavaParser - * to re-parse the document when the user presses ctrl+space. - */ - private class JavaAutoCompletion extends AutoCompletion { - - private RSyntaxTextArea textArea; - private String replacementTextPrefix; - - public JavaAutoCompletion(JavaCompletionProvider provider, - RSyntaxTextArea textArea) { - super(provider); - this.textArea = textArea; - } - - private String getCurrentLineText() { - - int caretPosition = textArea.getCaretPosition(); - Element root = textArea.getDocument().getDefaultRootElement(); - int line = root.getElementIndex(caretPosition); - Element elem = root.getElement(line); - int endOffset = elem.getEndOffset(); - int lineStart = elem.getStartOffset(); - - String text = ""; - try { - text = textArea.getText(lineStart, endOffset - lineStart).trim(); - } catch (BadLocationException e) { - e.printStackTrace(); - } - - return text; - - } - - /** - * Overridden to allow for prepending to the replacement text. This - * allows us to insert fully qualified class names. instead of - * unqualified ones, if necessary (i.e. if the user tries to - * auto-complete javax.swing.text.Document, but they've - * explicitly imported org.w3c.dom.Document - we need to - * insert the fully qualified name in that case). - */ - @Override - protected String getReplacementText(Completion c, Document doc, - int start, int len) { - String text = super.getReplacementText(c, doc, start, len); - if (replacementTextPrefix != null) { - text = replacementTextPrefix + text; - replacementTextPrefix = null; - } - return text; - } - - /** - * Determines whether the class name being completed has been imported, - * and if it hasn't, returns the import statement that should be added - * for it. Alternatively, if the class hasn't been imported, but a class - * with the same (unqualified) name HAS been imported, this method sets - * things up so the fully-qualified version of this class's name is - * inserted.

    - * - * Thanks to Guilherme Joao Frantz and Jonatas Schuler for helping with - * the patch! - * - * @param c The completion being inserted. - * @return Whether an import was added. - */ - private ImportToAddInfo getShouldAddImport(ClassCompletion cc) { - - String text = getCurrentLineText(); - - // Make sure we're not currently typing an import statement. - if (!text.startsWith("import ")) { - - JavaCompletionProvider provider = (JavaCompletionProvider) getCompletionProvider(); - CompilationUnit cu = provider.getCompilationUnit(); - int offset = 0; - boolean alreadyImported = false; - - // Try to bail early, if possible. - if (cu == null) { // Can never happen, right? - return null; - } - if ("java.lang".equals(cc.getPackageName())) { - // Package java.lang is "imported" by default. - return null; - } - - String className = cc.getClassName(false); - String fqClassName = cc.getClassName(true); - - // If the completion is in the same package as the source we're - // editing (or both are in the default package), bail. - int lastClassNameDot = fqClassName.lastIndexOf('.'); - boolean ccInPackage = lastClassNameDot > -1; - Package pkg = cu.getPackage(); - if (ccInPackage && pkg != null) { - String ccPkg = fqClassName.substring(0, lastClassNameDot); - String pkgName = pkg.getName(); - if (ccPkg.equals(pkgName)) { - return null; - } - } else if (!ccInPackage && pkg == null) { - return null; - } - - // Loop through all import statements. - Iterator i = cu.getImportIterator(); - for (; i.hasNext();) { - - ImportDeclaration id = i.next(); - offset = id.getNameEndOffset() + 1; - - // Pulling in static methods, etc. from a class - skip - if (id.isStatic()) { - continue; - } // Importing all classes in the package... - else if (id.isWildcard()) { - // NOTE: Class may be in default package... - if (lastClassNameDot > -1) { - String imported = id.getName(); - int dot = imported.lastIndexOf('.'); - String importedPkg = imported.substring(0, dot); - String classPkg = fqClassName.substring(0, lastClassNameDot); - if (importedPkg.equals(classPkg)) { - alreadyImported = true; - break; - } - } - } // Importing a single class from a package... - else { - - String fullyImportedClassName = id.getName(); - int dot = fullyImportedClassName.lastIndexOf('.'); - String importedClassName = fullyImportedClassName. - substring(dot + 1); - - // If they explicitly imported a class with the - // same name, but it's in a different package, then - // the user is required to fully-qualify the class - // in their code (if unqualified, it would be - // assumed to be of the type of the qualified - // class). - if (className.equals(importedClassName)) { - offset = -1; // Means "must fully qualify" - if (fqClassName.equals(fullyImportedClassName)) { - alreadyImported = true; - } - break; - } - - } - - } - - // If the class wasn't imported, we'll need to add an - // import statement! - if (!alreadyImported) { - - StringBuilder importToAdd = new StringBuilder(); - - // If there are no previous imports, add the import - // statement after the package line (if any). - if (offset == 0) { - if (pkg != null) { - offset = pkg.getNameEndOffset() + 1; - // Keep an empty line between package and imports. - importToAdd.append('\n'); - } - } - - // We read through all imports, but didn't find our class. - // Add a new import statement after the last one. - if (offset > -1) { - //System.out.println(classCompletion.getAlreadyEntered(textArea)); - if (offset > 0) { - importToAdd.append("\nimport ").append(fqClassName).append(';'); - } else { - importToAdd.append("import ").append(fqClassName).append(";\n"); - } - // TODO: Determine whether the imports are alphabetical, - // and if so, add the new one alphabetically. - return new ImportToAddInfo(offset, importToAdd.toString()); - } // Otherwise, either the class was imported, or a class - // with the same name was explicitly imported. - else { - // Another class with the same name was imported. - // We must insert the fully-qualified class name - // so the compiler resolves the correct class. - int dot = fqClassName.lastIndexOf('.'); - if (dot > -1) { - String pkgName = fqClassName.substring(0, dot + 1); - replacementTextPrefix = pkgName; - } - } - - } - - } - - return null; - - } - - /** - * Overridden to handle special cases, because sometimes Java code - * completions will edit more in the source file than just the text at - * the current caret position. - */ - @Override - protected void insertCompletion(Completion c, - boolean typedParamListStartChar) { - - ImportToAddInfo importInfo = null; - - // We special-case class completions because they may add import - // statements to the top of our source file. We don't add the - // (possible) new import statement until after the completion is - // inserted; that way, when we treat it as an atomic undo/redo, - // when the user undoes the completion, the caret stays in the - // code instead of jumping to the import. - if (c instanceof ClassCompletion) { - importInfo = getShouldAddImport((ClassCompletion) c); - if (importInfo != null) { - textArea.beginAtomicEdit(); - } - } - - try { - super.insertCompletion(c, typedParamListStartChar); - if (importInfo != null) { - textArea.insert(importInfo.text, importInfo.offs); - } - } finally { - // Be safe and always pair beginAtomicEdit() and endAtomicEdit() - textArea.endAtomicEdit(); - } - - } - - @Override - protected int refreshPopupWindow() { - // Force the parser to re-parse - JavaParser parser = getParser(textArea); - RSyntaxDocument doc = (RSyntaxDocument) textArea.getDocument(); - String style = textArea.getSyntaxEditingStyle(); - parser.parse(doc, style); - return super.refreshPopupWindow(); - } - - } - - /** - * Listens for various events in a text area editing Java (in particular, - * caret events, so we can track the "active" code block). - */ - private class Listener implements CaretListener, ActionListener { - - private RSyntaxTextArea textArea; - private Timer t; - - public Listener(RSyntaxTextArea textArea) { - this.textArea = textArea; - textArea.addCaretListener(this); - t = new Timer(650, this); - t.setRepeats(false); - } - - public void actionPerformed(ActionEvent e) { - - JavaParser parser = getParser(textArea); - if (parser == null) { - return; // Shouldn't happen - } - CompilationUnit cu = parser.getCompilationUnit(); - - // Highlight the line range of the Java method being edited in the - // gutter. - if (cu != null) { // Should always be true - int dot = textArea.getCaretPosition(); - Point p = cu.getEnclosingMethodRange(dot); - if (p != null) { - try { - int startLine = textArea.getLineOfOffset(p.x); - // Unterminated blocks can end in Integer.MAX_VALUE - int endOffs = Math.min(p.y, - textArea.getDocument().getLength()); - int endLine = textArea.getLineOfOffset(endOffs); - textArea.setActiveLineRange(startLine, endLine); - } catch (BadLocationException ble) { - ble.printStackTrace(); - } - } else { - textArea.setActiveLineRange(-1, -1); - } - } - - } - - public void caretUpdate(CaretEvent e) { - t.restart(); - } - - /** - * Should be called whenever Java language support is removed from a - * text area. - */ - public void uninstall() { - textArea.removeCaretListener(this); - } - - } - -} diff --git a/src/main/java/org/fife/rsta/ac/bsh/JavaLinkGenerator.java b/src/main/java/org/fife/rsta/ac/bsh/JavaLinkGenerator.java deleted file mode 100644 index 1bc6a96e..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/JavaLinkGenerator.java +++ /dev/null @@ -1,268 +0,0 @@ -/* - * 02/17/2013 - * - * Copyright (C) 2013 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh; - -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import javax.swing.text.BadLocationException; - -import org.fife.rsta.ac.bsh.rjc.ast.CodeBlock; -import org.fife.rsta.ac.bsh.rjc.ast.CompilationUnit; -import org.fife.rsta.ac.bsh.rjc.ast.FormalParameter; -import org.fife.rsta.ac.bsh.rjc.ast.LocalVariable; -import org.fife.rsta.ac.bsh.rjc.ast.Member; -import org.fife.rsta.ac.bsh.rjc.ast.Method; -import org.fife.rsta.ac.bsh.rjc.ast.TypeDeclaration; -import org.fife.ui.rsyntaxtextarea.LinkGenerator; -import org.fife.ui.rsyntaxtextarea.LinkGeneratorResult; -import org.fife.ui.rsyntaxtextarea.RSyntaxDocument; -import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; -import org.fife.ui.rsyntaxtextarea.RSyntaxUtilities; -import org.fife.ui.rsyntaxtextarea.SelectRegionLinkGeneratorResult; -import org.fife.ui.rsyntaxtextarea.Token; -import org.fife.ui.rsyntaxtextarea.TokenImpl; - - -/** - * Checks for hyperlink-able tokens under the mouse position when Ctrl is - * pressed (Cmd on OS X). Currently this class only checks for accessible - * members in the current file only (e.g. no members in super classes, no other - * classes on the classpath, etc.). So naturally, there is a lot of room for - * improvement. IDE-style applications, for example, would want to check - * for members in super-classes, and open their source on click events. - * - * @author Robert Futrell - * @version 1.0 - */ -// TODO: Anonymous inner classes probably aren't handled well. -class JavaLinkGenerator implements LinkGenerator { - - private JavaLanguageSupport jls; - - - JavaLinkGenerator(JavaLanguageSupport jls) { - this.jls = jls; - } - - - /** - * Checks if the token at the specified offset is possibly a "click-able" - * region. - * - * @param textArea The text area. - * @param offs The offset, presumably at the mouse position. - * @return A result object. - */ - private IsLinkableCheckResult checkForLinkableToken( - RSyntaxTextArea textArea, int offs) { - - IsLinkableCheckResult result = null; - - if (offs>=0) { - - try { - - int line = textArea.getLineOfOffset(offs); - Token first = textArea.getTokenListForLine(line); - RSyntaxDocument doc = (RSyntaxDocument)textArea.getDocument(); - Token prev = null; - - for (Token t=first; t!=null && t.isPaintable(); t=t.getNextToken()) { - - if (t.containsPosition(offs)) { - - // RSTA's tokens are pooled and re-used, so we must - // defensively make a copy of the one we want to keep! - Token token = new TokenImpl(t); - boolean isMethod = false; - - if (prev==null) { - prev = RSyntaxUtilities.getPreviousImportantToken( - doc, line-1); - } - if (prev!=null && prev.isSingleChar('.')) { - // Not a field or method defined in this class. - break; - } - - Token next = RSyntaxUtilities.getNextImportantToken( - t.getNextToken(), textArea, line); - if (next!=null && next.isSingleChar(Token.SEPARATOR, '(')) { - isMethod = true; - } - - result = new IsLinkableCheckResult(token, isMethod); - break; - - } - - else if (!t.isCommentOrWhitespace()) { - prev = t; - } - - } - - } catch (BadLocationException ble) { - ble.printStackTrace(); // Never happens - } - - } - - return result; - - } - - - /** - * {@inheritDoc} - */ - public LinkGeneratorResult isLinkAtOffset(RSyntaxTextArea textArea, - int offs) { - - int start = -1; - int end = -1; - - IsLinkableCheckResult result = checkForLinkableToken(textArea, offs); - if (result!=null) { - - JavaParser parser = jls.getParser(textArea); - CompilationUnit cu = parser.getCompilationUnit(); - Token t = result.token; - boolean method = result.method; - - if (cu!=null) { - - TypeDeclaration td = cu.getDeepestTypeDeclarationAtOffset(offs); - boolean staticFieldsOnly = false; - boolean deepestTypeDec = true; - boolean deepestContainingMemberStatic = false; - while (td!=null && start==-1) { - - // First, check for a local variable in methods/static blocks - if (!method && deepestTypeDec) { - - Iterator i = td.getMemberIterator(); - while (i.hasNext()) { - - Method m = null; // Nasty! Clean this code up - Member member = i.next(); - CodeBlock block = null; - - // Check if a method or static block contains offs - if (member instanceof Method) { - m = (Method)member; - if (m.getBodyContainsOffset(offs) && m.getBody()!=null) { - deepestContainingMemberStatic = m.isStatic(); - block = m.getBody().getDeepestCodeBlockContaining(offs); - } - } - else if (member instanceof CodeBlock) { - block = (CodeBlock)member; - deepestContainingMemberStatic = block.isStatic(); - block = block.getDeepestCodeBlockContaining(offs); - } - - // If so, scan its locals - if (block!=null) { - String varName = t.getLexeme(); - // Local variables first, in reverse order - List locals = block.getLocalVarsBefore(offs); - Collections.reverse(locals); - for (LocalVariable local : locals) { - if (varName.equals(local.getName())) { - start = local.getNameStartOffset(); - end = local.getNameEndOffset(); - } - } - // Then arguments, if any. - if (start==-1 && m!=null) { - for (int j=0; j i = method ? - td.getMethodIterator() : td.getFieldIterator(); - while (i.hasNext()) { - Member member = i.next(); - if (((!deepestContainingMemberStatic && !staticFieldsOnly) || member.isStatic()) && - varName.equals(member.getName())) { - start = member.getNameStartOffset(); - end = member.getNameEndOffset(); - break; - } - } - } - - // If still no match found, check parent type - if (start==-1) { - staticFieldsOnly |= td.isStatic(); - //td = td.isStatic() ? null : td.getParentType(); - td = td.getParentType(); - // Don't check for local vars in parent type methods. - deepestTypeDec = false; - } - - } - - } - - if (start>-1) { - return new SelectRegionLinkGeneratorResult(textArea, t.getOffset(), - start, end); - } - - } - - return null; - - } - - - /** - * The result of checking whether a region of code under the mouse is - * possibly link-able. - */ - private static class IsLinkableCheckResult { - - /** - * The token under the mouse position. - */ - private Token token; - - /** - * Whether the token is a method invocation (as opposed to a local - * variable or field). - */ - private boolean method; - - private IsLinkableCheckResult(Token token, boolean method) { - this.token = token; - this.method = method; - } - - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/JavaParamListCellRenderer.java b/src/main/java/org/fife/rsta/ac/bsh/JavaParamListCellRenderer.java deleted file mode 100644 index c2196ddc..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/JavaParamListCellRenderer.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 12/16/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh; - -import java.awt.Component; -import java.awt.Dimension; -import javax.swing.JList; - - -/** - * The renderer used for parameter completions (for methods) in Java. - * - * @author Robert Futrell - * @version 1.0 - */ -public class JavaParamListCellRenderer extends JavaCellRenderer { - - - public JavaParamListCellRenderer() { - // Param completions don't display type info, etc., because all - // completions for a single parameter have the same type (or subclass - // that type). - setSimpleText(true); - } - - - /** - * Returns the preferred size of a particular cell. Note that the parent - * class {@link JavaCellRenderer} doesn't override this method, because - * it doesn't use the cells to dictate the preferred size of the list, due - * to the large number of completions it shows at a time. - */ - @Override - public Dimension getPreferredSize() { - Dimension d = super.getPreferredSize(); - d.width += 32; // Looks better when less scrunched. - return d; - } - - - /** - * Returns the renderer. - * - * @param list The list of choices being rendered. - * @param value The {@link Completion} being rendered. - * @param index The index into list being rendered. - * @param selected Whether the item is selected. - * @param hasFocus Whether the item has focus. - */ - @Override - public Component getListCellRendererComponent(JList list, Object value, - int index, boolean selected, boolean hasFocus) { - super.getListCellRendererComponent(list, value, index, selected, - hasFocus); - JavaSourceCompletion ajsc = (JavaSourceCompletion)value; - setIcon(ajsc.getIcon()); - return this; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/JavaParser.java b/src/main/java/org/fife/rsta/ac/bsh/JavaParser.java deleted file mode 100644 index f1e692c0..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/JavaParser.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh; - -import java.beans.PropertyChangeListener; -import java.beans.PropertyChangeSupport; -import java.io.IOException; -import javax.swing.text.Element; - -import org.fife.io.DocumentReader; -import org.fife.rsta.ac.bsh.rjc.ast.CompilationUnit; -import org.fife.rsta.ac.bsh.rjc.lexer.Scanner; -import org.fife.rsta.ac.bsh.rjc.notices.ParserNotice; -import org.fife.rsta.ac.bsh.rjc.parser.ASTFactory; -import org.fife.ui.rsyntaxtextarea.RSyntaxDocument; -import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; -import org.fife.ui.rsyntaxtextarea.parser.AbstractParser; -import org.fife.ui.rsyntaxtextarea.parser.DefaultParseResult; -import org.fife.ui.rsyntaxtextarea.parser.DefaultParserNotice; -import org.fife.ui.rsyntaxtextarea.parser.ParseResult; - - -/** - * Parses Java code in an RSyntaxTextArea.

    - * - * Like all RSTA Parsers, a JavaParser instance is notified - * when the RSTA's text content changes. After a small delay, it will parse - * the content as Java code, building an AST and looking for any errors. When - * parsing is complete, a property change event of type - * {@link #PROPERTY_COMPILATION_UNIT} is fired. Listeners can check the new - * value of the property for the {@link CompilationUnit} built that represents - * the source code in the text area. Note that the CompilationUnit - * may be incomplete if there were parsing/syntax errors (it will usually be - * complete "up to" the error in the content).

    - * - * This parser cannot be shared amongst multiple instances of - * RSyntaxTextArea.

    - * - * Please keep in mind that this class is a work-in-progress! - * - * @author Robert Futrell - * @version 0.5 - */ -public class JavaParser extends AbstractParser { - - /** - * The property change event that's fired when the document is re-parsed. - * Applications can listen for this property change and update themselves - * accordingly. - */ - public static final String PROPERTY_COMPILATION_UNIT = "CompilationUnit"; - - private CompilationUnit cu; - private PropertyChangeSupport support; - private DefaultParseResult result; - - - /** - * Constructor. - */ - public JavaParser(RSyntaxTextArea textArea) { - support = new PropertyChangeSupport(this); - result = new DefaultParseResult(this); - } - - - /** - * Adds all notices from the Java parser to the results object. - */ - private void addNotices(RSyntaxDocument doc) { - - result.clearNotices(); - int count = cu==null ? 0 : cu.getParserNoticeCount(); - - if (count==0) { - return; - } - - for (int i=0; i-1) { - int len = notice.getLength(); - result.addNotice(new DefaultParserNotice(this, - notice.getMessage(), notice.getLine(), offs, len)); - } - } - - } - - - public void addPropertyChangeListener(String prop, PropertyChangeListener l) { - support.addPropertyChangeListener(prop, l); - } - - - /** - * Returns the compilation unit from the last time the text area was - * parsed. - * - * @return The compilation unit, or null if it hasn't yet - * been parsed or an unexpected error occurred while parsing. - */ - public CompilationUnit getCompilationUnit() { - return cu; - } - - - public int getOffset(RSyntaxDocument doc, ParserNotice notice) { - Element root = doc.getDefaultRootElement(); - Element elem = root.getElement(notice.getLine()); - int offs = elem.getStartOffset() + notice.getColumn(); - return offs>=elem.getEndOffset() ? -1 : offs; - } - - - /** - * {@inheritDoc} - */ - public ParseResult parse(RSyntaxDocument doc, String style) { - - cu = null; - result.clearNotices(); - // Always spell check all lines, for now. - int lineCount = doc.getDefaultRootElement().getElementCount(); - result.setParsedLines(0, lineCount-1); - - DocumentReader r = new DocumentReader(doc); - Scanner scanner = new Scanner(r); - scanner.setDocument(doc); - ASTFactory fact = new ASTFactory(); - long start = System.currentTimeMillis(); - try { - cu = fact.getCompilationUnit("SomeFile.java", scanner); // TODO: Real name? - long time = System.currentTimeMillis() - start; - result.setParseTime(time); - } catch (IOException ioe) { - result.setError(ioe); -// ioe.printStackTrace(); - } - - r.close(); - - addNotices(doc); - support.firePropertyChange(PROPERTY_COMPILATION_UNIT, null, cu); - return result; - - } - - - public void removePropertyChangeListener(String prop, PropertyChangeListener l) { - support.removePropertyChangeListener(prop, l); - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/JavaShorthandCompletion.java b/src/main/java/org/fife/rsta/ac/bsh/JavaShorthandCompletion.java deleted file mode 100644 index ae3bed1b..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/JavaShorthandCompletion.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * 04/08/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh; - -import java.awt.Color; -import java.awt.Graphics; -import javax.swing.Icon; - -import org.fife.ui.autocomplete.CompletionProvider; -import org.fife.ui.autocomplete.ShorthandCompletion; - - -/** - * A completion for shorthand items that mimics the style seen in Eclipse. - * - * @author Robert Futrell - * @version 1.0 - */ -class JavaShorthandCompletion extends ShorthandCompletion implements - JavaSourceCompletion { - - private static final Color SHORTHAND_COLOR = new Color(0, 127, 174); - - - /** - * Constructor. - * - * @param provider - * @param inputText - * @param replacementText - */ - public JavaShorthandCompletion(CompletionProvider provider, - String inputText, String replacementText) { - super(provider, inputText, replacementText); - } - - - /** - * Constructor. - * - * @param provider - * @param inputText - * @param replacementText - * @param shortDesc - */ - public JavaShorthandCompletion(CompletionProvider provider, - String inputText, String replacementText, String shortDesc) { - super(provider, inputText, replacementText, shortDesc); - } - - - /** - * {@inheritDoc} - */ - @Override - public Icon getIcon() { - return IconFactory.get().getIcon(IconFactory.TEMPLATE_ICON); - } - - - /** - * {@inheritDoc} - */ - public void rendererText(Graphics g, int x, int y, boolean selected) { - renderText(g, getInputText(), getReplacementText(), x, y, selected); - } - - - /** - * Renders a completion in the style of a short-hand completion. - * - * @param g The graphics context. - * @param input The text the user enters to display this completion. - * @param shortDesc An optional short description of the completion. - * @param x The x-offset at which to paint. - * @param y The y-offset at which to paint. - * @param selected Whether this completion choice is selected. - */ - public static void renderText(Graphics g, String input, String shortDesc, - int x, int y, boolean selected) { - Color orig = g.getColor(); - if (!selected && shortDesc!=null) { - g.setColor(SHORTHAND_COLOR); - } - g.drawString(input, x, y); - if (shortDesc!=null) { - x += g.getFontMetrics().stringWidth(input); - if (!selected) { - g.setColor(orig); - } - String temp = " - "; - g.drawString(temp, x, y); - x += g.getFontMetrics().stringWidth(temp); - if (!selected) { - g.setColor(Color.GRAY); - } - g.drawString(shortDesc, x, y); - } - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/JavaShorthandCompletionCache.java b/src/main/java/org/fife/rsta/ac/bsh/JavaShorthandCompletionCache.java deleted file mode 100644 index 819a88e5..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/JavaShorthandCompletionCache.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * 07/22/2012 - * - * Copyright (C) 2012 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh; - -import java.util.ResourceBundle; - -import org.fife.rsta.ac.ShorthandCompletionCache; -import org.fife.ui.autocomplete.BasicCompletion; -import org.fife.ui.autocomplete.DefaultCompletionProvider; - - -/** - * A cache of basic template and comment completions for Java, e.g. - * System.out.println(). - * - * @see ShorthandCompletionCache - * @author Steve - */ -public class JavaShorthandCompletionCache extends ShorthandCompletionCache { - - private static final String MSG = "org.fife.rsta.ac.bsh.resources"; - private static final ResourceBundle msg = ResourceBundle.getBundle(MSG); - - public JavaShorthandCompletionCache(DefaultCompletionProvider - templateProvider, DefaultCompletionProvider commentsProvider) { - - super(templateProvider, commentsProvider); - String template = null; - - //load defaults - template = "System.out.println(${});${cursor}"; - addShorthandCompletion(new JavaTemplateCompletion(templateProvider, "sysout", "sysout", template, - msg.getString("sysout.shortDesc"), msg.getString("sysout.summary"))); - - template = "System.err.println(${});${cursor}"; - addShorthandCompletion(new JavaTemplateCompletion(templateProvider, "syserr", "syserr", template, - msg.getString("syserr.shortDesc"), msg.getString("syserr.summary"))); - - template = - "for (int ${i} = 0; ${i} < ${array}.length; ${i}++) {\n\t${cursor}\n}"; - addShorthandCompletion(new JavaTemplateCompletion(templateProvider, "for", "for-loop-array", template, - msg.getString("for.array.shortDesc"), msg.getString("for.array.summary"))); - - template = "for (int ${i} = 0; ${i} < ${10}; ${i}++) {\n\t${cursor}\n}"; - addShorthandCompletion(new JavaTemplateCompletion(templateProvider, "for", "for-loop", - template, msg.getString("for.loop.shortDesc"), msg.getString("for.loop.summary"))); - - template = "if (${condition}) {\n\t${cursor}\n}"; - addShorthandCompletion(new JavaTemplateCompletion(templateProvider, "if", "if-cond", - template, msg.getString("if.cond.shortDesc"), msg.getString("if.cond.summary"))); - - template = "if (${condition}) {\n\t${cursor}\n}\nelse {\n\t\n}"; - addShorthandCompletion(new JavaTemplateCompletion(templateProvider, "if", "if-else", - template, msg.getString("if.else.shortDesc"), msg.getString("if.else.summary"))); - - template = "do {\n\t${cursor}\n} while (${condition});"; - addShorthandCompletion(new JavaTemplateCompletion(templateProvider, "do", "do-loop", template, - msg.getString("do.shortDesc"), msg.getString("do.summary"))); - - template = "while (${condition}) {\n\t${cursor}\n}"; - addShorthandCompletion(new JavaTemplateCompletion(templateProvider, "while", "while-cond", - template, msg.getString("while.shortDesc"), msg.getString("while.summary"))); - - template = "new Runnable() {\n\tpublic void run() {\n\t\t${cursor}\n\t}\n}"; - addShorthandCompletion(new JavaTemplateCompletion(templateProvider, "runnable", "runnable", template, - msg.getString("runnable.shortDesc"))); - - template = "switch (${key}) {\n\tcase ${value}:\n\t\t${cursor}\n\t\tbreak;\n\tdefault:\n\t\tbreak;\n}"; - addShorthandCompletion(new JavaTemplateCompletion(templateProvider, "switch", "switch-statement", - template, msg.getString("switch.case.shortDesc"), msg.getString("switch.case.summary"))); - - template = "try {\n\t ${cursor} \n} catch (${err}) {\n\t\n}"; - addShorthandCompletion(new JavaTemplateCompletion(templateProvider, "try", "try-catch", - template, msg.getString("try.catch.shortDesc"), msg.getString("try.catch.summary"))); - - template = "catch (${err}) {\n\t${cursor}\n}"; - addShorthandCompletion(new JavaTemplateCompletion(templateProvider, "catch", "catch-block", - template, msg.getString("catch.block.shortDesc"), msg.getString("catch.block.summary"))); - - /** Comments **/ - addCommentCompletion(new BasicCompletion(commentsProvider, "TODO:", null, msg.getString("todo"))); - addCommentCompletion(new BasicCompletion(commentsProvider, "FIXME:", null, msg.getString("fixme"))); - - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/JavaSourceCompletion.java b/src/main/java/org/fife/rsta/ac/bsh/JavaSourceCompletion.java deleted file mode 100644 index d536aff5..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/JavaSourceCompletion.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh; - -import java.awt.Graphics; - -import org.fife.ui.autocomplete.Completion; - - -/** - * Interface for Java source code completions. - * - * @author Robert Futrell - * @version 1.0 - */ -public interface JavaSourceCompletion extends Completion { - - - /** - * Force subclasses to override equals(). - * TODO: Remove me - */ - public boolean equals(Object obj); - - - /** - * Used by {@link JavaCellRenderer} to render this completion choice. - * - * @param g - * @param x - * @param y - * @param selected - */ - public void rendererText(Graphics g, int x, int y, boolean selected); - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/JavaTemplateCompletion.java b/src/main/java/org/fife/rsta/ac/bsh/JavaTemplateCompletion.java deleted file mode 100644 index 6b00b082..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/JavaTemplateCompletion.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 06/25/2012 - * - * Copyright (C) 2012 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh; - -import java.awt.Graphics; -import javax.swing.Icon; - -import org.fife.ui.autocomplete.CompletionProvider; -import org.fife.ui.autocomplete.TemplateCompletion; - - -/** - * A template completion for Java. - * - * @author Robert Futrell - * @version 1.0 - */ -public class JavaTemplateCompletion extends TemplateCompletion - implements JavaSourceCompletion { - - private String icon; - - - public JavaTemplateCompletion(CompletionProvider provider, - String inputText, String definitionString, String template) { - this(provider, inputText, definitionString, template, null); - } - - - public JavaTemplateCompletion(CompletionProvider provider, - String inputText, String definitionString, String template, - String shortDesc) { - this(provider, inputText, definitionString, template, shortDesc, null); - } - - - public JavaTemplateCompletion(CompletionProvider provider, - String inputText, String definitionString, String template, - String shortDesc, String summary) { - super(provider, inputText, definitionString, template, shortDesc, summary); - setIcon(IconFactory.TEMPLATE_ICON); - } - - - @Override - public Icon getIcon() { - return IconFactory.get().getIcon(icon); - } - - - public void rendererText(Graphics g, int x, int y, boolean selected) { - JavaShorthandCompletion.renderText(g, getInputText(), - getShortDescription(), x, y, selected); - } - - - public void setIcon(String iconId) { - this.icon = iconId; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/JavadocUrlHandler.java b/src/main/java/org/fife/rsta/ac/bsh/JavadocUrlHandler.java deleted file mode 100644 index d461703c..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/JavadocUrlHandler.java +++ /dev/null @@ -1,371 +0,0 @@ -/* - * 05/09/2012 - * - * Copyright (C) 2012 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh; - -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URL; -import java.util.List; -import javax.swing.UIManager; -import javax.swing.event.HyperlinkEvent; - -import org.fife.rsta.ac.LanguageSupportFactory; -import org.fife.rsta.ac.bsh.classreader.ClassFile; -import org.fife.rsta.ac.bsh.classreader.FieldInfo; -import org.fife.rsta.ac.bsh.classreader.MethodInfo; -import org.fife.ui.autocomplete.Completion; -import org.fife.ui.autocomplete.DescWindowCallback; -import org.fife.ui.autocomplete.ExternalURLHandler; -import org.fife.ui.autocomplete.Util; -import org.fife.ui.rsyntaxtextarea.modes.JavaTokenRegistration; - - -/** - * Handles hyperlinks that are clicked in Javadoc for code completions. It's - * assumed that the links found were created via - * {@link org.fife.rsta.ac.bsh.Util#docCommentToHtml(String)}, so that things - * such as "@see" links are interpreted properly. - * - * @author Robert Futrell - * @version 1.0 - */ -public class JavadocUrlHandler implements ExternalURLHandler { - - - /** - * Returns the parent package backupCount levels up from - * the package specified. - * - * @param pkg A package. - * @param backupCount The number of packages "up" to go. - * @return The parent package. - */ - private String doBackups(String pkg, int backupCount) { - int lastDot = pkg.length(); - while (lastDot>-1 && backupCount>0) { - lastDot = pkg.lastIndexOf('.', lastDot); - backupCount--; - } - return lastDot>-1 ? pkg.substring(0, lastDot) : ""; - } - - - /** - * Returns the Java language support. - * - * @return The Java language support - */ - private JavaLanguageSupport getJavaLanguageSupport() { - return (JavaLanguageSupport)LanguageSupportFactory.get(). - getSupportFor(JavaTokenRegistration.SYNTAX_STYLE); - } - - - /** - * Returns the anchor portion of a (relative) URL. - * - * @param url The URL. - * @return The anchor, or null if none. - */ - private static final String getAnchor(String url) { - int pound = url.indexOf('#'); - return pound>-1 ? url.substring(pound+1) : null; - } - - - /** - * Gets the arguments from a method signature. - * - * @param methodSignature The method signature. - * @return The arguments, or an empty array if none. - */ - private static final String[] getArgs(String methodSignature) { - - String[] args = null; - - int lparen = methodSignature.indexOf('('); - if (lparen>-1) { - int rparen = methodSignature.indexOf(')', lparen); // Should be len-1 - if (rparen>-1 && rparen>lparen+1) { - String temp = methodSignature.substring(lparen, rparen); - args = temp.split("\\s*,\\s*"); - } - } - - if (args==null) { - args = new String[0]; - } - return args; - - } - - - /** - * Returns the class for a completion (class completions return the class - * itself, member completions return the enclosing class). - */ - private String getClass(Completion c, String desc) { - - String clazz = null; - - if (c instanceof ClassCompletion) { - clazz = ((ClassCompletion)c).getClassName(true); - } - else if (c instanceof MemberCompletion) { - MemberCompletion mc = (MemberCompletion)c; - clazz = mc.getEnclosingClassName(true); - } - else { - System.err.println("Can't determine class from completion type: " + - c.getClass() + " (" + c.toString() + ") - href: " + desc); - } - - return clazz; - - } - - - /** - * Returns the package of the specified completion. - * - * @param c The completion. - * @param desc The description text being parsed. Used for errors if we - * cannot determine the package. - * @return The package. - */ - private String getPackage(Completion c, String desc) { - - String pkg = null; - - if (c instanceof ClassCompletion) { - pkg = ((ClassCompletion)c).getPackageName(); - } - else if (c instanceof MemberCompletion) { - String definedIn = ((MemberCompletion)c).getEnclosingClassName(true); - if (definedIn!=null) { - int lastDot = definedIn.lastIndexOf('.'); - if (lastDot>-1) { - pkg = definedIn.substring(0, lastDot); - } - } - } - else { - System.err.println("Can't determine package from completion type: " + - c.getClass() + " (" + c.toString() + ") - href: " + desc); - } - - return pkg; - - } - - - /** - * Returns whether the text is a relative URL to other Javadoc. - * - * @param text A link in Javadoc. - * @return Whether the link is a relative path to more Javadoc. - */ - private boolean isRelativeUrl(String text) { - // Javadoc is always ".html", and we support full URL's elsewhere. - final String[] EXTS = { ".html", ".htm" }; - for (int i=0; i-1 || - text.indexOf(EXTS[i]+"?")>-1) { - return true; - } - } - return false; - } - - - /** - * {@inheritDoc} - */ - public void urlClicked(HyperlinkEvent e, Completion c, - DescWindowCallback callback) { - - // A "real" URL (starts with http://, for example) should be opened - // in the system browser, not the completion description window. - URL url = e.getURL(); - if (url!=null) { - // Try loading in external browser (Java 6+ only). - try { - Util.browse(new URI(url.toString())); - } catch (/*IO*/URISyntaxException ioe) { - UIManager.getLookAndFeel().provideErrorFeedback(null); - ioe.printStackTrace(); - } - return; - } - - // A relative path URL (no leading "http://") results in a null URL. - // Class should be in the same package as the one we're currently - // viewing. Example: java.lang.String class documentation - String desc = e.getDescription(); - //System.out.println(desc); - if (desc!=null) { - - if (isRelativeUrl(desc)) { - int ext = desc.indexOf(".htm"); - if (ext>-1) { - - // Could be link. A - // popular href format is "../../util/Formatter.html#syntax". - // We must determine "relative" package location. - String anchor = getAnchor(desc); - String clazz = desc.substring(0, ext); - int backups = 0; - while (clazz.startsWith("../")) { - backups++; - clazz = clazz.substring(3); - } - clazz = clazz.replace('/', '.'); - - String pkg = getPackage(c, desc); - if (pkg!=null) { - clazz = doBackups(pkg, backups) + "." + clazz; - JavaLanguageSupport jls = getJavaLanguageSupport(); - ClassFile cf = jls.getJarManager().getClassEntry(clazz); - if (cf!=null) { - ClassCompletion cc = new ClassCompletion(c.getProvider(), cf); - callback.showSummaryFor(cc, anchor); - } - } - - } - } - - // Could be format "com.mycompany.pkg.MyClass", with optional - // #method() (for example, @see's). - else { - - JavaLanguageSupport jls = getJavaLanguageSupport(); - - String clazz = desc; - String member = null; - int pound = desc.indexOf('#'); - if (pound>-1) { // TODO: Handle properly - member = clazz.substring(pound+1); - clazz = clazz.substring(0, pound); - } - - // Just a class name, i.e. "String", "java.util.regex.Pattern". - if (member==null) { - boolean guessedPackage = false; - if (clazz.indexOf('.')==-1) { - String pkg = getPackage(c, desc); - if (pkg!=null) { - clazz = pkg + "." + clazz; - } - guessedPackage = true; - } - ClassFile cf = jls.getJarManager().getClassEntry(clazz); - if (cf==null && guessedPackage) { - // Wasn't in the same package as "c", try java.lang - int lastDot = clazz.lastIndexOf('.'); - clazz = "java.lang." + clazz.substring(lastDot+1); - cf = jls.getJarManager().getClassEntry(clazz); - } - if (cf!=null) { - ClassCompletion cc = new ClassCompletion(c.getProvider(), cf); - callback.showSummaryFor(cc, null); - } - else { - UIManager.getLookAndFeel().provideErrorFeedback(null); - System.err.println("Unknown class: " + clazz); - } - } - - // Member specified, such as "String#format(...)", - // "java.util.regex.Pattern.compile(...)", or "#method()". - else { - - boolean guessedPackage = false; - - if (pound==0) { // Member of this class (i.e. "#foobar(bas)") - // "clazz" was incorrect previously in this case - clazz = getClass(c, desc); - } - else { // i.e. "String#CASE_INSENSITIVE_ORDER" - // If no package specified, assume clazz is in the same - // package as the currently displayed completion. - if (clazz.indexOf('.')==-1) { - String pkg = getPackage(c, desc); - if (pkg!=null) { - clazz = pkg + "." + clazz; - } - guessedPackage = true; - } - } - - ClassFile cf = jls.getJarManager().getClassEntry(clazz); - if (cf==null && guessedPackage) { - // Wasn't in the same package as "c", try java.lang - int lastDot = clazz.lastIndexOf('.'); - clazz = "java.lang." + clazz.substring(lastDot+1); - cf = jls.getJarManager().getClassEntry(clazz); - } - if (cf!=null) { - - Completion memberCompletion = null; - - int lparen = member.indexOf('('); - if (lparen==-1) { // A field, or method with args omitted - FieldInfo fi = cf.getFieldInfoByName(member); - if (fi!=null) { // Try fields first, it's most likely - memberCompletion = new FieldCompletion(c.getProvider(), fi); - } - else { // Try methods second - List miList = cf.getMethodInfoByName(member, -1); - if (miList!=null && miList.size()>0) { - MethodInfo mi = miList.get(0);// Just show the first if multiple - memberCompletion = new MethodCompletion(c.getProvider(), mi); - } - } - } - - else { - String[] args = getArgs(member); - String methodName = member.substring(0, lparen); - List miList = cf.getMethodInfoByName(methodName, args.length); - if (miList!=null && miList.size()>0) { - if (miList.size()>1) { - // TODO: Pick correct overload based on args - System.err.println("Multiple overload support not yet implemented"); - } - else { - MethodInfo mi = miList.get(0); - memberCompletion = new MethodCompletion(c.getProvider(), mi); - } - } - } - - if (memberCompletion!=null) { - callback.showSummaryFor(memberCompletion, null); - } - - } - else { - UIManager.getLookAndFeel().provideErrorFeedback(null); - System.err.println("Unknown class: " + clazz + - " (href: " + desc + ")"); - } - - } - - } - - } - - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/LocalVariableCompletion.java b/src/main/java/org/fife/rsta/ac/bsh/LocalVariableCompletion.java deleted file mode 100644 index a5672e82..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/LocalVariableCompletion.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh; - -import java.awt.Graphics; -import javax.swing.Icon; - -import org.fife.rsta.ac.bsh.rjc.ast.LocalVariable; -import org.fife.ui.autocomplete.CompletionProvider; - -class LocalVariableCompletion extends AbstractJavaSourceCompletion { - - private LocalVariable localVar; - - /** - * The relevance of local variables. This allows local variables to be - * "higher" in the completion list than other types. - */ - private static final int RELEVANCE = 4; - - - public LocalVariableCompletion(CompletionProvider provider, - LocalVariable localVar) { - super(provider, localVar.getName()); - this.localVar = localVar; - setRelevance(RELEVANCE); - } - - - @Override - public boolean equals(Object obj) { - return (obj instanceof LocalVariableCompletion) && - ((LocalVariableCompletion)obj).getReplacementText(). - equals(getReplacementText()); - } - - - @Override - public Icon getIcon() { - return IconFactory.get().getIcon(IconFactory.LOCAL_VARIABLE_ICON); - } - - - @Override - public String getToolTipText() { - return localVar.getType() + " " + localVar.getName(); - } - - - @Override - public int hashCode() { - return getReplacementText().hashCode(); // Match equals() - } - - - public void rendererText(Graphics g, int x, int y, boolean selected) { - StringBuilder sb = new StringBuilder(); - sb.append(localVar.getName()); - sb.append(" : "); - sb.append(localVar.getType()); - g.drawString(sb.toString(), x, y); - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/MemberCompletion.java b/src/main/java/org/fife/rsta/ac/bsh/MemberCompletion.java deleted file mode 100644 index abef594f..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/MemberCompletion.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh; - -import org.fife.rsta.ac.bsh.IconFactory.IconData; - - -/** - * Extra methods defined by a completion for a Java member (fields and methods). - * - * @author Robert Futrell - * @version 1.0 - */ -interface MemberCompletion extends JavaSourceCompletion { - - - /** - * Returns the name of the enclosing class. - * - * @param fullyQualified Whether the name returned should be fully - * qualified. - * @return The class name. - */ - public String getEnclosingClassName(boolean fullyQualified); - - - /** - * Returns the signature of this member. - * - * @return The signature. - */ - public String getSignature(); - - - /** - * Returns the type of this member (the return type for methods). - * - * @return The type of this member. - */ - public String getType(); - - - /** - * Returns whether this member is deprecated. - * - * @return Whether this member is deprecated. - */ - public boolean isDeprecated(); - - - /** - * Meta data about the member. Member completions will be constructed - * from a concrete instance of this interface. This is because there are - * two sources that member completions come from - parsing Java source - * files and parsing compiled class files (in libraries). - */ - public static interface Data extends IconData { - - /** - * Returns the name of the enclosing class. - * - * @param fullyQualified Whether the name returned should be fully - * qualified. - * @return The class name. - */ - public String getEnclosingClassName(boolean fullyQualified); - - /** - * Returns the signature of this member. - * - * @return The signature. - * @see MemberCompletion#getSignature() - */ - public String getSignature(); - - /** - * Returns the summary description (should be HTML) for this member. - * - * @return The summary description, or null if there is - * none. - * @see MemberCompletion#getSummary() - */ - public String getSummary(); - - /** - * Returns the type of this member (the return type for methods). - * - * @return The type of this member. - * @see MemberCompletion#getType() - */ - public String getType(); - - /** - * Returns whether this member is a constructor. - * - * @return Whether this member is a constructor. - */ - public boolean isConstructor(); - - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/MethodCompletion.java b/src/main/java/org/fife/rsta/ac/bsh/MethodCompletion.java deleted file mode 100644 index 8ba5fda4..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/MethodCompletion.java +++ /dev/null @@ -1,332 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh; - -import java.awt.Color; -import java.awt.FontMetrics; -import java.awt.Graphics; -import java.util.ArrayList; -import java.util.List; -import javax.swing.Icon; -import javax.swing.text.JTextComponent; - -import org.fife.rsta.ac.bsh.classreader.MethodInfo; -import org.fife.rsta.ac.bsh.rjc.ast.FormalParameter; -import org.fife.rsta.ac.bsh.rjc.ast.Method; -import org.fife.rsta.ac.bsh.rjc.lang.Type; -import org.fife.ui.autocomplete.Completion; -import org.fife.ui.autocomplete.CompletionProvider; -import org.fife.ui.autocomplete.FunctionCompletion; - - -/** - * A completion for a Java method. This completion gets its information from - * one of two sources: - * - *

    - * - * @author Robert Futrell - * @version 1.0 - */ -class MethodCompletion extends FunctionCompletion implements MemberCompletion { - - /** - * The data source for our completion attributes. - */ - private Data data; - - /** - * Used to compare this method completion with another. - */ - private String compareString; - - /** - * The relevance of methods. This allows methods to be "higher" in - * the completion list than other types. - */ - private static final int NON_CONSTRUCTOR_RELEVANCE = 2; - - - /** - * Creates a completion for a method discovered when parsing a Java - * source file. - * - * @param provider - * @param m Meta data about the method. - */ - public MethodCompletion(CompletionProvider provider, Method m) { - - // NOTE: "void" might not be right - I think this might be constructors - super(provider, m.getName(), m.getType()==null ? "void" : m.getType().toString()); - setDefinedIn(m.getParentTypeDeclaration().getName()); - this.data = new MethodData(m); - setRelevanceAppropriately(); - - int count = m.getParameterCount(); - List params = new ArrayList(count); - for (int i=0; i params = new ArrayList(paramTypes.length); - for (int i=0; iCompletion to compare to. - * @return The sort order. - */ - @Override - public int compareTo(Completion c2) { - - int rc = -1; - - if (c2==this) { - rc = 0; - } - - else if (c2 instanceof MethodCompletion) { - rc = getCompareString().compareTo( - ((MethodCompletion)c2).getCompareString()); - } - - else if (c2!=null) { - rc = toString().compareToIgnoreCase(c2.toString()); - if (rc==0) { // Same text value - String clazz1 = getClass().getName(); - clazz1 = clazz1.substring(clazz1.lastIndexOf('.')); - String clazz2 = c2.getClass().getName(); - clazz2 = clazz2.substring(clazz2.lastIndexOf('.')); - rc = clazz1.compareTo(clazz2); - } - } - - return rc; - - } - - - @Override - public boolean equals(Object obj) { - return (obj instanceof MethodCompletion) && - //((MethodCompletion)obj).getSignature().equals(getSignature()); - ((MethodCompletion)obj).getCompareString().equals(getCompareString()); - } - - - @Override - public String getAlreadyEntered(JTextComponent comp) { - String temp = getProvider().getAlreadyEnteredText(comp); - int lastDot = temp.lastIndexOf('.'); - if (lastDot>-1) { - temp = temp.substring(lastDot+1); - } - return temp; - } - - - /** - * Returns a string used to compare this method completion to another. - * - * @return The comparison string. - */ - private String getCompareString() { - - /* - * This string compares the following parts of methods in this order, - * to optimize sort order in completion lists. - * - * 1. First, by name - * 2. Next, by number of parameters. - * 3. Finally, by parameter type. - */ - - if (compareString==null) { - StringBuilder sb = new StringBuilder(getName()); - // NOTE: This will fail if a method has > 99 parameters (!) - int paramCount = getParamCount(); - if (paramCount<10) { - sb.append('0'); - } - sb.append(paramCount); - for (int i=0; i-1) { - shortType = shortType.substring(dot+1); - } - - // Draw the method signature - String sig = mc.getSignature(); - FontMetrics fm = g.getFontMetrics(); - g.drawString(sig, x, y); - int newX = x + fm.stringWidth(sig); - if (mc.isDeprecated()) { - int midY = y + fm.getDescent() - fm.getHeight()/2; - g.drawLine(x, midY, newX, midY); - } - x = newX; - - // Append the return type - StringBuilder sb = new StringBuilder(" : ").append(shortType); - sb.append(" - "); - String s = sb.toString(); - g.drawString(s, x, y); - x += fm.stringWidth(s); - - // Append the type of the containing class of this member. - Color origColor = g.getColor(); - if (!selected) { - g.setColor(Color.GRAY); - } - g.drawString(mc.getEnclosingClassName(false), x, y); - if (!selected) { - g.setColor(origColor); - } - - } - - - /** - * {@inheritDoc} - */ - @Override - public String toString() { - return getSignature(); - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/MethodData.java b/src/main/java/org/fife/rsta/ac/bsh/MethodData.java deleted file mode 100644 index 0e48824c..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/MethodData.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh; - -import org.fife.rsta.ac.bsh.MemberCompletion.Data; -import org.fife.rsta.ac.bsh.rjc.ast.Method; -import org.fife.rsta.ac.bsh.rjc.ast.TypeDeclaration; -import org.fife.rsta.ac.bsh.rjc.lang.Modifiers; -import org.fife.rsta.ac.bsh.rjc.lang.Type; - - -/** - * Metadata about a method as read from a Java source file. This class is - * used by instances of {@link MethodCompletion}. - * - * @author Robert Futrell - * @version 1.0 - */ -class MethodData implements Data { - - private Method method; - - - public MethodData(Method method) { - this.method = method; - } - - - /** - * {@inheritDoc} - */ - public String getEnclosingClassName(boolean fullyQualified) { - // NOTE: This check isn't really necessary, but is here just in case - // there's a bug in the parsing code. - TypeDeclaration td = method.getParentTypeDeclaration(); - if (td==null) { - new Exception("No parent type declaration for: " + getSignature()). - printStackTrace(); - return ""; - } - return td.getName(fullyQualified); - } - - - public String getIcon() { - - String key = null; - - Modifiers mod = method.getModifiers(); - if (mod==null) { - key = IconFactory.METHOD_DEFAULT_ICON; - } - else if (mod.isPrivate()) { - key = IconFactory.METHOD_PRIVATE_ICON; - } - else if (mod.isProtected()) { - key = IconFactory.METHOD_PROTECTED_ICON; - } - else if (mod.isPublic()) { - key = IconFactory.METHOD_PUBLIC_ICON; - } - else { - key = IconFactory.METHOD_DEFAULT_ICON; - } - - return key; - - } - - - public String getSignature() { - return method.getNameAndParameters(); - } - - - public String getSummary() { - String docComment = method.getDocComment(); - return docComment!=null ? docComment : method.toString(); - } - - - public String getType() { - Type type = method.getType(); - return type==null ? "void" : type.toString(); - } - - - public boolean isAbstract() { - return method.getModifiers().isAbstract(); - } - - - public boolean isConstructor() { - return method.isConstructor(); - } - - - public boolean isDeprecated() { - return method.isDeprecated(); - } - - - public boolean isFinal() { - return method.getModifiers().isFinal(); - } - - - public boolean isStatic() { - return method.getModifiers().isStatic(); - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/MethodInfoData.java b/src/main/java/org/fife/rsta/ac/bsh/MethodInfoData.java deleted file mode 100644 index 68a3130c..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/MethodInfoData.java +++ /dev/null @@ -1,371 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.fife.rsta.ac.bsh.MemberCompletion.Data; -import org.fife.rsta.ac.bsh.buildpath.SourceLocation; -import org.fife.rsta.ac.bsh.classreader.ClassFile; -import org.fife.rsta.ac.bsh.classreader.MethodInfo; -import org.fife.rsta.ac.bsh.classreader.Util; -import org.fife.rsta.ac.bsh.rjc.ast.CompilationUnit; -import org.fife.rsta.ac.bsh.rjc.ast.FormalParameter; -import org.fife.rsta.ac.bsh.rjc.ast.Member; -import org.fife.rsta.ac.bsh.rjc.ast.Method; -import org.fife.rsta.ac.bsh.rjc.ast.TypeDeclaration; - - -/** - * Metadata about a method as read from a class file. This class is used by - * instances of {@link MethodCompletion}. - * - * @author Robert Futrell - * @version 1.0 - */ -class MethodInfoData implements Data { - - /** - * The parent completion provider. - */ - private SourceCompletionProvider provider; - - /** - * The actual metadata. - */ - private MethodInfo info; - - /** - * Cached method parameter names. - */ - private List paramNames; - - - /** - * Constructor. - * - * @param info - * @param provider - */ - public MethodInfoData(MethodInfo info, SourceCompletionProvider provider) { - this.info = info; - this.provider = provider; - } - - - /** - * {@inheritDoc} - */ - public String getEnclosingClassName(boolean fullyQualified) { - return info.getClassFile().getClassName(fullyQualified); - } - - - /** - * {@inheritDoc} - */ - public String getIcon() { - - String key = null; - int flags = info.getAccessFlags(); - - if (Util.isDefault(flags)) { - key = IconFactory.METHOD_DEFAULT_ICON; - } - else if (Util.isPrivate(flags)) { - key = IconFactory.METHOD_PRIVATE_ICON; - } - else if (Util.isProtected(flags)) { - key = IconFactory.METHOD_PROTECTED_ICON; - } - else if (Util.isPublic(flags)) { - key = IconFactory.METHOD_PUBLIC_ICON; - } - else { - key = IconFactory.METHOD_DEFAULT_ICON; - } - - return key; - - } - - - /** - * Scours the source in a location (zip file, directory), looking for a - * particular class's source. If it is found, it is parsed, and the - * {@link Method} for this method (if any) is returned. - * - * @param loc The zip file, jar file, or directory to look in. - * @param cf The {@link ClassFile} representing the class of this method. - * @return The method, or null if it cannot be found, or an - * IO error occurred. - */ - private Method getMethodFromSourceLoc(SourceLocation loc, ClassFile cf) { - - Method res = null; - CompilationUnit cu = org.fife.rsta.ac.bsh.Util. - getCompilationUnitFromDisk(loc, cf); - - // If the class's source was found and successfully parsed, look for - // this method. - if (cu!=null) { - - Iterator i = cu.getTypeDeclarationIterator(); - while (i.hasNext()) { - - TypeDeclaration td = i.next(); - String typeName = td.getName(); - - // Avoid inner classes, etc. - if (typeName.equals(cf.getClassName(false))) { - - // Get all overloads of this method with the number of - // parameters we're looking for. 99% of the time, there - // will only be 1, the method we're looking for. - List contenders = null; - for (int j=0; j(1); // Usually just 1 - } - contenders.add(m2); - } - } - } - - // We found some matches. - if (contenders!=null) { - - // Common case - only 1 overload with the desired - // number of parameters => it must be our method. - if (contenders.size()==1) { - res = contenders.get(0); - } - - // More than 1 overload with the same number of - // parameters... we decide which contender is the one - // we're looking for by checking each of its - // parameters' types and making sure they're correct. - else { - for (Method method : contenders) { - boolean match = true; - for (int p=0; pnull if it cannot be determined. - * - * @param index The index of the parameter. - * @return The name of the parameter, or null. - */ - public String getParameterName(int index) { - - // First, check whether the debugging attribute was enabled at - // compilation, and the parameter name is embedded in the class file. - // This method takes priority because it *likely* matches a name - // specified in Javadoc, and is much faster for us to fetch (it's - // already parsed). - String name = info.getParameterName(index); - - // Otherwise... - if (name==null) { - - // Next, check the attached source, if any (lazily parsed). - if (paramNames==null) { - - paramNames = new ArrayList(1); - int offs = 0; - String rawSummary = getSummary(); - - // If there's attached source with Javadoc for this method... - if (rawSummary!=null && rawSummary.startsWith("/**")) { - - int nextParam = 0; - int summaryLen = rawSummary.length(); - - while ((nextParam=rawSummary.indexOf("@param", offs))>-1) { - int temp = nextParam + "@param".length() + 1; - while (tempnull if the method has no javadoc, - * the class's source was not found, or an IO error occurred. - */ - private String getSummaryFromSourceLoc(SourceLocation loc, ClassFile cf) { - Method method = getMethodFromSourceLoc(loc, cf); - return method!=null ? method.getDocComment() : null; - } - - - /** - * {@inheritDoc} - */ - public String getType() { - return info.getReturnTypeString(false); - } - - - public boolean isAbstract() { - return info.isAbstract(); - } - - - /** - * {@inheritDoc} - */ - public boolean isConstructor() { - return info.isConstructor(); - } - - - /** - * {@inheritDoc} - */ - public boolean isDeprecated() { - return info.isDeprecated(); - } - - - public boolean isFinal() { - return info.isFinal(); - } - - - public boolean isStatic() { - return info.isStatic(); - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/PackageMapNode.java b/src/main/java/org/fife/rsta/ac/bsh/PackageMapNode.java deleted file mode 100644 index f74ba8fd..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/PackageMapNode.java +++ /dev/null @@ -1,385 +0,0 @@ -/* - * 04/04/2015 - * - * Copyright (C) 2015 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh; - -import java.io.IOException; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.SortedMap; -import java.util.TreeMap; - -import org.fife.rsta.ac.bsh.buildpath.LibraryInfo; -import org.fife.rsta.ac.bsh.classreader.ClassFile; -import org.fife.ui.autocomplete.Completion; -import org.fife.ui.autocomplete.CompletionProvider; - - -/** - * A data structure modeling all classes in a jar or directory, or on a - * classpath. It's a recursive mapping of Strings to either - * Maps or {@link ClassFile}s (which are lazily created and - * may be null). At each level of the nested map, the string - * key is a package name iff its corresponding value is a Map. - * Examine that Map's contents to explore the contents of - * that package. If the corresponding value is a ClassFile, - * then the string key's value is the name of that class. Finally, if - * the corresponding value is null, then the string key's - * value is the name of a class, but its contents have not yet been - * loaded for use by the code completion library (ClassFiles - * are lazily loaded to conserve memory). - */ -public class PackageMapNode { - - /** - * A mapping of sub-package name to the sub-packages and classes under it. - */ - private SortedMap subpackages; - - /** - * A mapping of class file names to class files in this package. The - * actual {@link ClassFile} values are lazily instantiated, so any map - * entry with a value of null simply has not been created - * yet. - */ - private SortedMap classFiles; - - - public PackageMapNode() { - subpackages = - new TreeMap(String.CASE_INSENSITIVE_ORDER); - classFiles = - new TreeMap(String.CASE_INSENSITIVE_ORDER); - } - - - /** - * Adds entries for a fully-qualified class name, of the form - * "org/fife/util/DynamicIntArray.class". This method should - * only be called on the "root" node of a package map. - * - * @param className A fully-qualified class name of the form described - * above. - */ - public void add(String className) { - - String[] tokens = Util.splitOnChar(className, '/'); - PackageMapNode pmn = this; - - for (int i=0; i.' character. This should be (the start of) a - * fully-qualified class, interface, or enum name. - * @param addTo The list to add completion choices to. - */ - public void addCompletions(LibraryInfo info, CompletionProvider provider, - String[] pkgNames, Set addTo) { - - PackageMapNode map = this; - for (int i=0; i largest valid class char - - // First add completions for matching subpackage names. - SortedMap subpackages = map.subpackages.subMap(fromKey, toKey); - if (!subpackages.isEmpty()) { - - StringBuilder sb = new StringBuilder(); - for (int j=0; j entry : subpackages.entrySet()) { - String completionPackageName = entry.getKey(); - String text = earlierPackages + completionPackageName; - addTo.add(new PackageNameCompletion(provider, text, fromKey)); - } - - } - - // Next, add completions for matching class names - SortedMap sm = map.classFiles.subMap(fromKey, toKey); - for (Map.Entry entry : sm.entrySet()) { - - String key = entry.getKey(); - ClassFile cf = entry.getValue(); - - // The ClassFile may have already been loaded for this one - if (cf != null) { - boolean inPkg = false; // TODO: Pass me in - if (inPkg || org.fife.rsta.ac.bsh.classreader.Util.isPublic(cf.getAccessFlags())) { - addTo.add(new ClassCompletion(provider, cf)); - } - } - - // If the ClassFile isn't yet cached - else { - String[] items = new String[pkgNames.length]; - System.arraycopy(pkgNames, 0, items, 0, pkgNames.length-1); - items[items.length-1] = key; - cf = getClassEntry(info, items); - if (cf!=null) { - boolean inPkg = false; // TODO: Pass me in - if (inPkg || org.fife.rsta.ac.bsh.classreader.Util.isPublic(cf.getAccessFlags())) { - addTo.add(new ClassCompletion(provider, cf)); - } - } - else { - // This should never happen - class name without a ClassFile - } - } - - } - - } - - - /** - * Removes the cache of all ClassFiles from this package - * map. - * - * @return The number of class file entries removed. - */ - public int clearClassFiles() { - return clearClassFilesImpl(this); - } - - - private int clearClassFilesImpl(PackageMapNode pmn) { - - int clearedCount = 0; - - for (Map.Entry entry : pmn.classFiles.entrySet()) { - entry.setValue(null); - clearedCount++; - } - - for (Map.Entry entry : pmn.subpackages.entrySet()) { - clearedCount += clearClassFilesImpl(entry.getValue()); - } - - return clearedCount; - - } - - - public boolean containsClass(String className) { - - String[] items = className.split("\\."); - - PackageMapNode pmn = this; - for (int i=0; i addTo, - String[] pkgs, boolean inPkg) { - - PackageMapNode map = this; - - for (int i=0; i entry : map.classFiles.entrySet()) { - - ClassFile cf = entry.getValue(); - if (cf == null) { - StringBuilder name = new StringBuilder(pkgs[0]); - for (int j=1; jmap belongs to (i.e. - * all levels of packages scanned before this one), separated by - * '/'. - * @param addTo The list to add any matching ClassFiles to. - */ - void getClassesWithNamesStartingWith(LibraryInfo info, String prefix, - String currentPkg, List addTo) { - - final int prefixLen = prefix.length(); - - for (Map.Entry children : subpackages.entrySet()) { - String key = children.getKey(); - PackageMapNode child = children.getValue(); - child.getClassesWithNamesStartingWith(info, prefix, - currentPkg + key + "/", addTo); - } - - for (Map.Entry cfEntry : classFiles.entrySet()) { - // If value is null, we only lazily create the ClassFile if - // necessary (i.e. if the class name does match what they've - // typed). - String className = cfEntry.getKey(); - if (className.regionMatches(true, 0, prefix, 0, prefixLen)) { - ClassFile cf = cfEntry.getValue(); - if (cf==null) { - String fqClassName = currentPkg + className + ".class"; - try { - cf = info.createClassFile(fqClassName); - cfEntry.setValue(cf); // Update the map - } catch (IOException ioe) { - ioe.printStackTrace(); - } - } - if (cf!=null) { // possibly null if IOException above - addTo.add(cf); - } - } - } - - } - - - private static final void possiblyAddTo(Collection addTo, - ClassFile cf, boolean inPkg) { - if (inPkg || org.fife.rsta.ac.bsh.classreader.Util.isPublic(cf.getAccessFlags())) { - addTo.add(cf); - } - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/PackageNameCompletion.java b/src/main/java/org/fife/rsta/ac/bsh/PackageNameCompletion.java deleted file mode 100644 index 8cdfa52a..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/PackageNameCompletion.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh; - -import java.awt.Graphics; -import javax.swing.Icon; - -import org.fife.ui.autocomplete.CompletionProvider; - - -/** - * A completion that represents a package name. - * - * @author Robert Futrell - * @version 1.0 - */ -class PackageNameCompletion extends AbstractJavaSourceCompletion { - - - public PackageNameCompletion(CompletionProvider provider, String text, - String alreadyEntered) { - super(provider, text.substring(text.lastIndexOf('.')+1)); - } - - - @Override - public boolean equals(Object obj) { - return (obj instanceof PackageNameCompletion) && - ((PackageNameCompletion)obj).getReplacementText().equals(getReplacementText()); - } - - - @Override - public Icon getIcon() { - return IconFactory.get().getIcon(IconFactory.PACKAGE_ICON); - } - - - @Override - public int hashCode() { - return getReplacementText().hashCode(); - } - - - public void rendererText(Graphics g, int x, int y, boolean selected) { - g.drawString(getInputText(), x, y); - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/SourceCompletionProvider.java b/src/main/java/org/fife/rsta/ac/bsh/SourceCompletionProvider.java deleted file mode 100644 index 4a4487b6..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/SourceCompletionProvider.java +++ /dev/null @@ -1,1072 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh; - -import java.awt.Cursor; -import java.awt.Point; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; -import javax.swing.text.BadLocationException; -import javax.swing.text.JTextComponent; - -import org.fife.rsta.ac.ShorthandCompletionCache; -import org.fife.rsta.ac.bsh.buildpath.LibraryInfo; -import org.fife.rsta.ac.bsh.buildpath.SourceLocation; -import org.fife.rsta.ac.bsh.classreader.ClassFile; -import org.fife.rsta.ac.bsh.classreader.FieldInfo; -import org.fife.rsta.ac.bsh.classreader.MemberInfo; -import org.fife.rsta.ac.bsh.classreader.MethodInfo; -import org.fife.rsta.ac.bsh.rjc.ast.CodeBlock; -import org.fife.rsta.ac.bsh.rjc.ast.CompilationUnit; -import org.fife.rsta.ac.bsh.rjc.ast.Field; -import org.fife.rsta.ac.bsh.rjc.ast.FormalParameter; -import org.fife.rsta.ac.bsh.rjc.ast.ImportDeclaration; -import org.fife.rsta.ac.bsh.rjc.ast.LocalVariable; -import org.fife.rsta.ac.bsh.rjc.ast.Member; -import org.fife.rsta.ac.bsh.rjc.ast.Method; -import org.fife.rsta.ac.bsh.rjc.ast.NormalClassDeclaration; -import org.fife.rsta.ac.bsh.rjc.ast.TypeDeclaration; -import org.fife.rsta.ac.bsh.rjc.lang.Type; -import org.fife.rsta.ac.bsh.rjc.lang.TypeArgument; -import org.fife.rsta.ac.bsh.rjc.lang.TypeParameter; -import org.fife.ui.autocomplete.Completion; -import org.fife.ui.autocomplete.DefaultCompletionProvider; -import org.fife.ui.rsyntaxtextarea.RSyntaxDocument; -import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; -import org.fife.ui.rsyntaxtextarea.RSyntaxUtilities; -import org.fife.ui.rsyntaxtextarea.Token; - - -/** - * Parses a Java AST for code completions. It currently scans the following: - * - *
      - *
    • Import statements - *
    • Method names - *
    • Field names - *
    - * - * Also, if the caret is inside a method, local variables up to the caret - * position are also returned. - * - * @author Robert Futrell - * @version 1.0 - */ -class SourceCompletionProvider extends DefaultCompletionProvider { - - /** - * The parent completion provider. - */ - private JavaCompletionProvider javaProvider; - - /** - * Used to get information about what classes match imports. - */ - private JarManager jarManager; - - private static final String JAVA_LANG_PACKAGE = "java.lang.*"; - private static final String THIS = "this"; - - //Shorthand completions (templates and comments) - private ShorthandCompletionCache shorthandCache; - /** - * Constructor. - */ - public SourceCompletionProvider() { - this(null); - } - - - /** - * Constructor. - * - * @param jarManager The jar manager for this provider. - */ - public SourceCompletionProvider(JarManager jarManager) { - if (jarManager==null) { - jarManager = new JarManager(); - } - this.jarManager = jarManager; - setParameterizedCompletionParams('(', ", ", ')'); - setAutoActivationRules(false, "."); // Default - only activate after '.' - setParameterChoicesProvider(new SourceParamChoicesProvider()); - } - - - private void addCompletionsForStaticMembers(Set set, - CompilationUnit cu, ClassFile cf, String pkg) { - - // Check us first, so if we override anything, we get the "newest" - // version. - int methodCount = cf.getMethodCount(); - for (int i=0; i set, - CompilationUnit cu, ClassFile cf, String pkg, - Map typeParamMap) { - - // Reset this class's type-arguments-to-type-parameters map, so that - // when methods and fields need to know type arguments, they can query - // for them. - cf.setTypeParamsToTypeArgs(typeParamMap); - - // Check us first, so if we override anything, we get the "newest" - // version. - int methodCount = cf.getMethodCount(); - for (int i=0; i retVal) { - - Type type = var.getType(); - String pkg = cu.getPackageName(); - - if (type.isArray()) { - ClassFile cf = getClassFileFor(cu, "java.lang.Object"); - addCompletionsForExtendedClass(retVal, cu, cf, pkg, null); - FieldCompletion fc = FieldCompletion. - createLengthCompletion(this, type); - retVal.add(fc); - } - - else if (!type.isBasicType()) { - String typeStr = type.getName(true, false); - ClassFile cf = getClassFileFor(cu, typeStr); - if (cf!=null) { - Map typeParamMap = createTypeParamMap(type, cf); - addCompletionsForExtendedClass(retVal, cu, cf, pkg, typeParamMap); - } - } - - } - - - /** - * Adds simple shorthand completions relevant to Java. - * - * @param set The set to add to. - */ - private void addShorthandCompletions(Set set) { - if(shorthandCache != null) { - set.addAll(shorthandCache.getShorthandCompletions()); - } - } - - /** - * Set template completion cache for source completion provider. - * - * @param shorthandCache The new cache. - */ - public void setShorthandCache(ShorthandCompletionCache shorthandCache) { - this.shorthandCache = shorthandCache; - } - - - /** - * Gets the {@link ClassFile} for a class. - * - * @param cu The compilation unit being parsed. - * @param className The name of the class (fully qualified or not). - * @return The {@link ClassFile} for the class, or null if - * cf represents java.lang.Object (or - * if the super class could not be determined). - */ - private ClassFile getClassFileFor(CompilationUnit cu, String className) { - - //System.err.println(">>> Getting class file for: " + className); - if (className==null) { - return null; - } - - ClassFile superClass = null; - - // Determine the fully qualified class to grab - if (!Util.isFullyQualified(className)) { - - // Check in this source file's package first - String pkg = cu.getPackageName(); - if (pkg!=null) { - String temp = pkg + "." + className; - superClass = jarManager.getClassEntry(temp); - } - - // Next, go through the imports (order is important) - if (superClass==null) { - Iterator i = cu.getImportIterator(); - while (i.hasNext()) { - ImportDeclaration id = i.next(); - String imported = id.getName(); - if (imported.endsWith(".*")) { - String temp = imported.substring( - 0, imported.length()-1) + className; - superClass = jarManager.getClassEntry(temp); - if (superClass!=null) { - break; - } - } - else if (imported.endsWith("." + className)) { - superClass = jarManager.getClassEntry(imported); - break; - } - } - } - - // Finally, try java.lang - if (superClass==null) { - String temp = "java.lang." + className; - superClass = jarManager.getClassEntry(temp); - } - - } - - else { - superClass = jarManager.getClassEntry(className); - } - - return superClass; - - } - - - /** - * Adds completions for local variables in a method. - * - * @param set - * @param method - * @param offs The caret's offset into the source. This should be inside - * of method. - */ - private void addLocalVarCompletions(Set set, Method method, - int offs) { - - for (int i=0; iblock. - */ - private void addLocalVarCompletions(Set set, CodeBlock block, - int offs) { - - for (int i=0; ioffs) { - break; - } - } - - } - - - /** - * Adds a jar to read from. - * - * @param info The jar to add. If this is null, then - * the current JVM's main JRE jar (rt.jar, or classes.jar on OS X) - * will be added. If this jar has already been added, adding it - * again will do nothing (except possibly update its attached source - * location). - * @throws IOException If an IO error occurs. - * @see #getJars() - * @see #removeJar(File) - */ - public void addJar(LibraryInfo info) throws IOException { - jarManager.addClassFileSource(info); - } - - - /** - * Checks whether the user is typing a completion for a String member after - * a String literal. - * - * @param comp The text component. - * @param alreadyEntered The text already entered. - * @param cu The compilation unit being parsed. - * @param set The set to add possible completions to. - * @return Whether the user is indeed typing a completion for a String - * literal member. - */ - private boolean checkStringLiteralMember(JTextComponent comp, - String alreadyEntered, - CompilationUnit cu, Set set) { - - boolean stringLiteralMember = false; - - int offs = comp.getCaretPosition() - alreadyEntered.length() - 1; - if (offs>1) { - RSyntaxTextArea textArea = (RSyntaxTextArea)comp; - RSyntaxDocument doc = (RSyntaxDocument)textArea.getDocument(); - try { - //System.out.println(doc.charAt(offs) + ", " + doc.charAt(offs+1)); - if (doc.charAt(offs)=='"' && doc.charAt(offs+1)=='.') { - int curLine = textArea.getLineOfOffset(offs); - Token list = textArea.getTokenListForLine(curLine); - Token prevToken = RSyntaxUtilities.getTokenAtOffset(list, offs); - if (prevToken!=null && - prevToken.getType()==Token.LITERAL_STRING_DOUBLE_QUOTE) { - ClassFile cf = getClassFileFor(cu, "java.lang.String"); - addCompletionsForExtendedClass(set, cu, cf, - cu.getPackageName(), null); - stringLiteralMember = true; - } - else { - System.out.println(prevToken); - } - } - } catch (BadLocationException ble) { // Never happens - ble.printStackTrace(); - } - } - - return stringLiteralMember; - - } - - - /** - * Removes all jars from the "build path." - * - * @see #removeJar(File) - * @see #addJar(LibraryInfo) - * @see #getJars() - */ - public void clearJars() { - jarManager.clearClassFileSources(); - // The memory used by the completions can be quite large, so go ahead - // and clear out the completions list so no-longer-needed ones are - // eligible for GC. - clear(); - } - - - /** - * Creates and returns a mapping of type parameters to type arguments. - * - * @param type The type of a variable/field/etc. whose fields/methods/etc. - * are being code completed, as declared in the source. This - * includes type arguments. - * @param cf The ClassFile representing the actual type of - * the variable/field/etc. being code completed - * @return A mapping of type parameter names to type arguments (both - * Strings). - */ - private Map createTypeParamMap(Type type, ClassFile cf) { - Map typeParamMap = null; - List typeArgs = type.getTypeArguments(type.getIdentifierCount()-1); - if (typeArgs!=null) { - typeParamMap = new HashMap(); - List paramTypes = cf.getParamTypes(); - // Should be the same size! Otherwise, the source code has - // too many/too few type arguments listed for this type. - int min = Math.min(paramTypes==null ? 0 : paramTypes.size(), - typeArgs.size()); - for (int i=0; i getCompletionsAt(JTextComponent tc, Point p) { - getCompletionsImpl(tc); // Force loading of completions - return super.getCompletionsAt(tc, p); - } - - - /** - * {@inheritDoc} - */ - @Override - protected List getCompletionsImpl(JTextComponent comp) { - - comp.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); - - try { - - completions = new ArrayList();//completions.clear(); - - CompilationUnit cu = javaProvider.getCompilationUnit(); - if (cu==null) { - return completions; // empty - } - - Set set = new TreeSet(); - - // Cut down the list to just those matching what we've typed. - // Note: getAlreadyEnteredText() never returns null - String text = getAlreadyEnteredText(comp); - - // Special case - end of a String literal - boolean stringLiteralMember = checkStringLiteralMember(comp, text, cu, - set); - - // Not after a String literal - regular code completion - if (!stringLiteralMember) { - - // Don't add shorthand completions if they're typing something - // qualified - if (text.indexOf('.')==-1) { - addShorthandCompletions(set); - } - - loadImportCompletions(set, text, cu); - - // Add completions for fully-qualified stuff (e.g. "com.sun.jav") - //long startTime = System.currentTimeMillis(); - jarManager.addCompletions(this, text, set); - //long time = System.currentTimeMillis() - startTime; - //System.out.println("jar completions loaded in: " + time); - - // Loop through all types declared in this source, and provide - // completions depending on in what type/method/etc. the caret's in. - loadCompletionsForCaretPosition(cu, comp, text, set); - - } - - // Do a final sort of all of our completions and we're good to go! - completions = new ArrayList(set); - Collections.sort(completions); - - // Only match based on stuff after the final '.', since that's what is - // displayed for all of our completions. - text = text.substring(text.lastIndexOf('.')+1); - - @SuppressWarnings("unchecked") - int start = Collections.binarySearch(completions, text, comparator); - if (start<0) { - start = -(start+1); - } - else { - // There might be multiple entries with the same input text. - while (start>0 && - comparator.compare(completions.get(start-1), text)==0) { - start--; - } - } - - @SuppressWarnings("unchecked") - int end = Collections.binarySearch(completions, text+'{', comparator); - end = -(end+1); - - return completions.subList(start, end); - - } finally { - comp.setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR)); - } - - } - - - /** - * Returns the jars on the "build path." - * - * @return A list of {@link LibraryInfo}s. Modifying a - * LibraryInfo in this list will have no effect on - * this completion provider; in order to do that, you must re-add - * the jar via {@link #addJar(LibraryInfo)}. If there are - * no jars on the "build path," this will be an empty list. - * @see #addJar(LibraryInfo) - */ - public List getJars() { - return jarManager.getClassFileSources(); - } - - - -public SourceLocation getSourceLocForClass(String className) { - return jarManager.getSourceLocForClass(className); -} - - /** - * Returns whether a method defined by a super class is accessible to - * this class. - * - * @param info Information about the member. - * @param pkg The package of the source currently being parsed. - * @return Whether or not the method is accessible. - */ - private boolean isAccessible(MemberInfo info, String pkg) { - - boolean accessible = false; - int access = info.getAccessFlags(); - - if (org.fife.rsta.ac.bsh.classreader.Util.isPublic(access) || - org.fife.rsta.ac.bsh.classreader.Util.isProtected(access)) { - accessible = true; - } - else if (org.fife.rsta.ac.bsh.classreader.Util.isDefault(access)) { - String pkg2 = info.getClassFile().getPackageName(); - accessible = (pkg==null && pkg2==null) || - (pkg!=null && pkg.equals(pkg2)); - } - - return accessible; - - } - - - /** - * {@inheritDoc} - */ - @Override - protected boolean isValidChar(char ch) { - return Character.isJavaIdentifierPart(ch) || ch=='.'; - } - - - /** - * Loads completions based on the current caret location in the source. In - * other words: - * - *
      - *
    • If the caret is anywhere in a class, the names of all methods and - * fields in the class are loaded. Methods and fields in super - * classes are also loaded. TODO: Get super methods/fields added - * correctly by access! - *
    • If the caret is in a field, local variables currently accessible - * are loaded. - *
    - * - * @param cu - * @param comp - * @param alreadyEntered - * @param retVal - */ - private void loadCompletionsForCaretPosition(CompilationUnit cu, - JTextComponent comp, String alreadyEntered, Set retVal) { - - // Get completions for all fields and methods of all type declarations. - - //long startTime = System.currentTimeMillis(); - int caret = comp.getCaretPosition(); - //List temp = new ArrayList(); - int start, end; - - int lastDot = alreadyEntered.lastIndexOf('.'); - boolean qualified = lastDot>-1; - String prefix = qualified ? alreadyEntered.substring(0, lastDot) : null; - - Iterator i = cu.getTypeDeclarationIterator(); - while (i.hasNext()) { - - TypeDeclaration td = i.next(); - start = td.getBodyStartOffset(); - end = td.getBodyEndOffset(); - - if (caret>start && caret<=end) { - loadCompletionsForCaretPosition(cu, comp, alreadyEntered, - retVal, td, prefix, caret); - } - - else if (caret - *
  • If the caret is anywhere in a class, the names of all methods and - * fields in the class are loaded. Methods and fields in super - * classes are also loaded. TODO: Get super methods/fields added - * correctly by access! - *
  • If the caret is in a field, local variables currently accessible - * are loaded. - * - * - * @param cu - * @param comp - * @param alreadyEntered - * @param retVal - */ - private void loadCompletionsForCaretPosition(CompilationUnit cu, - JTextComponent comp, String alreadyEntered, Set retVal, - TypeDeclaration td, String prefix, int caret) { - - // Do any child types first, so if any vars, etc. have duplicate names, - // we pick up the one "closest" to us first. - for (int i=0; i typeParamMap = new HashMap(); - if (td instanceof NormalClassDeclaration) { - NormalClassDeclaration ncd = (NormalClassDeclaration)td; - List typeParams = ncd.getTypeParameters(); - if (typeParams!=null) { - for (TypeParameter typeParam : typeParams) { - String typeVar = typeParam.getName(); - // For non-qualified completions, use type var name. - typeParamMap.put(typeVar, typeVar); - } - } - } - - // Get completions for this class's methods, fields and local - // vars. Do this before checking super classes so that, if - // we overrode anything, we get the "newest" version. - String pkg = cu.getPackageName(); - Iterator j = td.getMemberIterator(); - while (j.hasNext()) { - Member m = j.next(); - if (m instanceof Method) { - Method method = (Method)m; - if (prefix==null || THIS.equals(prefix)) { - retVal.add(new MethodCompletion(this, method)); - } - if (caret>=method.getBodyStartOffset() && caretnull if - * none. - * @param prefix The text up to the current caret position. This is - * guaranteed to be non-null not equal to - * "this". - * @param offs The offset of the caret in the document. - */ - private void loadCompletionsForCaretPositionQualified(CompilationUnit cu, - String alreadyEntered, Set retVal, - TypeDeclaration td, Method currentMethod, String prefix, int offs) { - - // TODO: Remove this restriction. - int dot = prefix.indexOf('.'); - if (dot>-1) { - System.out.println("[DEBUG]: Qualified non-this completions currently only go 1 level deep"); - return; - } - - // TODO: Remove this restriction. - else if (!prefix.matches("[A-Za-z_][A-Za-z0-9_\\$]*")) { - System.out.println("[DEBUG]: Only identifier non-this completions are currently supported"); - return; - } - - String pkg = cu.getPackageName(); - boolean matched = false; - - for (Iterator j=td.getMemberIterator(); j.hasNext(); ) { - - Member m = j.next(); - - // The prefix might be a field in the local class. - if (m instanceof Field) { - - Field field = (Field)m; - - if (field.getName().equals(prefix)) { - //System.out.println("FOUND: " + prefix + " (" + pkg + ")"); - Type type = field.getType(); - if (type.isArray()) { - ClassFile cf = getClassFileFor(cu, "java.lang.Object"); - addCompletionsForExtendedClass(retVal, cu, cf, pkg, null); - FieldCompletion fc = FieldCompletion. - createLengthCompletion(this, type); - retVal.add(fc); - } - else if (!type.isBasicType()) { - String typeStr = type.getName(true, false); - ClassFile cf = getClassFileFor(cu, typeStr); - // Add completions for extended class type chain - if (cf!=null) { - Map typeParamMap = createTypeParamMap(type, cf); - addCompletionsForExtendedClass(retVal, cu, cf, pkg, typeParamMap); - // Add completions for all implemented interfaces - // TODO: Only do this if type is abstract! - for (int i=0; i imports = cu.getImports(); - List matches = jarManager.getClassesWithUnqualifiedName( - prefix, imports); - if (matches!=null) { - for (int i=0; i retVal, - TypeDeclaration td, CodeBlock block, String prefix, int offs) { - - boolean found = false; - - for (int i=0; ioffs) { - break; - } - } - - } - - - /** - * Loads completions for a single import statement. - * - * @param importStr The import statement. - * @param pkgName The package of the source currently being parsed. - */ - private void loadCompletionsForImport(Set set, - String importStr, String pkgName) { - - if (importStr.endsWith(".*")) { - String pkg = importStr.substring(0, importStr.length()-2); - boolean inPkg = pkg.equals(pkgName); - List classes= jarManager.getClassesInPackage(pkg, inPkg); - for (ClassFile cf : classes) { - set.add(new ClassCompletion(this, cf)); - } - } - - else { - ClassFile cf = jarManager.getClassEntry(importStr); - if (cf!=null) { - set.add(new ClassCompletion(this, cf)); - } - } - - } - - - /** - * Loads completions for all import statements. - * - * @param cu The compilation unit being parsed. - */ - private void loadImportCompletions(Set set, String text, - CompilationUnit cu) { - - // Fully-qualified completions are handled elsewhere, so no need to - // duplicate the work here - if (text.indexOf('.')>-1) { - return; - } - - //long startTime = System.currentTimeMillis(); - - String pkgName = cu.getPackageName(); - loadCompletionsForImport(set, JAVA_LANG_PACKAGE, pkgName); - for (Iterator i=cu.getImportIterator(); i.hasNext(); ) { - ImportDeclaration id = i.next(); - String name = id.getName(); - if (!JAVA_LANG_PACKAGE.equals(name)) { - loadCompletionsForImport(set, name, pkgName); - } - } -// Collections.sort(completions); - - //long time = System.currentTimeMillis() - startTime; - //System.out.println("imports loaded in: " + time); - - } - - - /** - * Removes a jar from the "build path." - * - * @param jar The jar to remove. - * @return Whether the jar was removed. This will be false - * if the jar was not on the build path. - * @see #addJar(LibraryInfo) - * @see #getJars() - * @see #clearJars() - */ - public boolean removeJar(File jar) { - boolean removed = jarManager.removeClassFileSource(jar); - // The memory used by the completions can be quite large, so go ahead - // and clear out the completions list so no-longer-needed ones are - // eligible for GC. - if (removed) { - clear(); - } - return removed; - } - - - /** - * Sets the parent Java provider. - * - * @param javaProvider The parent completion provider. - */ - void setJavaProvider(JavaCompletionProvider javaProvider) { - this.javaProvider = javaProvider; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/SourceParamChoicesProvider.java b/src/main/java/org/fife/rsta/ac/bsh/SourceParamChoicesProvider.java deleted file mode 100644 index 0deb19f8..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/SourceParamChoicesProvider.java +++ /dev/null @@ -1,337 +0,0 @@ -/* - * 12/14/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh; - -import java.awt.Graphics; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import javax.swing.Icon; -import javax.swing.text.JTextComponent; - -import org.fife.rsta.ac.LanguageSupport; -import org.fife.rsta.ac.LanguageSupportFactory; -import org.fife.rsta.ac.bsh.rjc.ast.CodeBlock; -import org.fife.rsta.ac.bsh.rjc.ast.CompilationUnit; -import org.fife.rsta.ac.bsh.rjc.ast.Field; -import org.fife.rsta.ac.bsh.rjc.ast.FormalParameter; -import org.fife.rsta.ac.bsh.rjc.ast.LocalVariable; -import org.fife.rsta.ac.bsh.rjc.ast.Member; -import org.fife.rsta.ac.bsh.rjc.ast.Method; -import org.fife.rsta.ac.bsh.rjc.ast.NormalClassDeclaration; -import org.fife.rsta.ac.bsh.rjc.ast.NormalInterfaceDeclaration; -import org.fife.rsta.ac.bsh.rjc.ast.Package; -import org.fife.rsta.ac.bsh.rjc.ast.TypeDeclaration; -import org.fife.rsta.ac.bsh.rjc.lang.Type; -import org.fife.ui.autocomplete.BasicCompletion; -import org.fife.ui.autocomplete.Completion; -import org.fife.ui.autocomplete.CompletionProvider; -import org.fife.ui.autocomplete.EmptyIcon; -import org.fife.ui.autocomplete.ParameterChoicesProvider; -import org.fife.ui.autocomplete.ParameterizedCompletion; -import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; -import org.fife.ui.rsyntaxtextarea.modes.JavaTokenRegistration; - - -/** - * A parameter choices provider for Java methods.

    - * NOTE: This class is not thread-safe, but it's assumed that it is only - * ever called on the EDT, so it should be a non-issue. - * - * @author Robert Futrell - * @version 1.0 - */ -class SourceParamChoicesProvider implements ParameterChoicesProvider { - - /** - * The parent {@link JavaCompletionProvider}. - */ - private CompletionProvider provider; - - - /** - * Adds all accessible fields and getters of a specific type, from an - * extended class or implemented interface. - * - * @param type - * @param jm - * @param pkg - * @param list - */ - private void addPublicAndProtectedFieldsAndGetters(Type type, JarManager jm, - Package pkg, List list) { - - // TODO: Implement me. - - } - - - /** - * Gets all local variables, fields, and simple getters defined in a - * class, that are of a specific type, and are accessible from a given - * offset. - * - * @param ncd The class. - * @param type The type that the variables, fields, and (return value of) - * getters must be. - * @param offs The offset of the caret. - * @return The list of stuff, or an empty list if none are found. - */ - public List getLocalVarsFieldsAndGetters( - NormalClassDeclaration ncd, String type, int offs) { - - List members = new ArrayList(); - - if (!ncd.getBodyContainsOffset(offs)) { - return members; - } - - // First, if the offset is in a method, get any local variables in - // that method. - Method method = ncd.getMethodContainingOffset(offs); - if (method!=null) { - - // Parameters to the method - Iterator i = method.getParameterIterator(); - while (i.hasNext()) { - FormalParameter param = i.next(); - Type paramType = param.getType(); - if (isTypeCompatible(paramType, type)) { - //members.add(param.getName()); - members.add(new LocalVariableCompletion(provider, param)); - } - } - - // Local variables in the method - CodeBlock body = method.getBody(); - if (body!=null) { // Should always be true? - CodeBlock block = body.getDeepestCodeBlockContaining(offs); - List vars = block.getLocalVarsBefore(offs); - for (LocalVariable var : vars) { - Type varType = var.getType(); - if (isTypeCompatible(varType, type)) { - //members.add(var.getName()); - members.add(new LocalVariableCompletion(provider, var)); - } - } - } - - } - - // Next, any fields/getters taking no parameters (for simplicity) - // in this class. - for (Iterator i=ncd.getMemberIterator(); i.hasNext(); ) { - - Member member = i.next(); - - if (member instanceof Field) { - Type fieldType = member.getType(); - if (isTypeCompatible(fieldType, type)) { - //members.add(member.getName()); - members.add(new FieldCompletion(provider, (Field)member)); - } - } - else { // Method - method = (Method)member; - if (isSimpleGetter(method)) { - if (isTypeCompatible(method.getType(), type)) { - //members.add(member.getName() + "()"); - members.add(new MethodCompletion(provider, method)); - } - } - } - - } - - return members; - - } - - - /** - * {@inheritDoc} - */ - public List getParameterChoices(JTextComponent tc, - ParameterizedCompletion.Parameter param) { - - // Get the language support for Java - LanguageSupportFactory lsf = LanguageSupportFactory.get(); - LanguageSupport support = lsf.getSupportFor(JavaTokenRegistration.SYNTAX_STYLE); - JavaLanguageSupport jls = (JavaLanguageSupport)support; - JarManager jm = jls.getJarManager(); - - // Get the deepest TypeDeclaration AST containing the caret position - // for the source code in the editor. - RSyntaxTextArea textArea = (RSyntaxTextArea)tc; - JavaParser parser = jls.getParser(textArea); - if (parser==null) { - return null; - } - CompilationUnit cu = parser.getCompilationUnit(); - if (cu==null) { - return null; - } - int dot = tc.getCaretPosition(); - TypeDeclaration typeDec = cu.getDeepestTypeDeclarationAtOffset(dot); - if (typeDec==null) { - return null; - } - - List list = null; - Package pkg = typeDec.getPackage(); - provider = jls.getCompletionProvider(textArea); - - // If we're in a class, we'll have to check for local variables, etc. - if (typeDec instanceof NormalClassDeclaration) { - - // Get accessible members of this type. - NormalClassDeclaration ncd = (NormalClassDeclaration)typeDec; - list = getLocalVarsFieldsAndGetters(ncd, param.getType(), dot); -// list = typeDec.getAccessibleMembersOfType(param.getType(), dot); - - // Get accessible members of the extended type. - Type extended = ncd.getExtendedType(); - if (extended!=null) { - addPublicAndProtectedFieldsAndGetters(extended, jm, pkg, list); - } - - // Get accessible members of any implemented interfaces. - for (Iterator i=ncd.getImplementedIterator(); i.hasNext(); ) { - Type implemented = i.next(); - addPublicAndProtectedFieldsAndGetters(implemented,jm,pkg,list); - } - - - } - - // If we're an interface, local vars, etc. don't exist - else if (typeDec instanceof NormalInterfaceDeclaration) { - // Nothing to do - } - - // If we're in an enum... - else {//if (typeDec instanceof EnumDeclaration) { - // TODO: Implement me - } - - // Check for any public/protected fields/getters in enclosing type. - if (!typeDec.isStatic()) { - // TODO: Implement me. - } - - // Add defaults for common types - "0" for primitive numeric types, - // "null" for Objects, etc. - Object typeObj = param.getTypeObject(); - // TODO: Not all Parameters have typeObj set to a Type yet! Make me so - if (typeObj instanceof Type) { - Type type = (Type)typeObj; - if (type.isBasicType()) { - if (isPrimitiveNumericType(type)) { - list.add(new SimpleCompletion(provider, "0")); - } - else { // is a "boolean" type - list.add(new SimpleCompletion(provider, "false")); - list.add(new SimpleCompletion(provider, "true")); - } - } - else { - list.add(new SimpleCompletion(provider, "null")); - } - } - - // And we're done! - return list; - - } - - - private boolean isPrimitiveNumericType(Type type) { - String str = type.getName(true); - return "byte".equals(str) || "float".equals(str) || - "double".equals(str) || "int".equals(str) || - "short".equals(str) || "long".equals(str); - } - - - /** - * Returns whether a method is a no-argument getter method. - * - * @param method The method. - * @return Whether it is a no-argument getter. - */ - private boolean isSimpleGetter(Method method) { - return method.getParameterCount()==0 && - method.getName().startsWith("get"); - } - - - /** - * Returns whether a Type and a type name are type - * compatible. This method currently is a sham! - * - * @param type - * @param typeName - * @return - */ - // TODO: Get me working! Probably need better parameters passed in!!! - private boolean isTypeCompatible(Type type, String typeName) { - - String typeName2 = type.getName(false); - - // Remove generics info for now - // TODO: Handle messy generics cases - int lt = typeName2.indexOf('<'); - if (lt>-1) { - String arrayDepth = null; - int brackets = typeName2.indexOf('[', lt); - if (brackets>-1) { - arrayDepth = typeName2.substring(brackets); - } - typeName2 = typeName2.substring(lt); - if (arrayDepth!=null) { - typeName2 += arrayDepth; - } - } - - return typeName2.equalsIgnoreCase(typeName); - - } - - - /** - * A very simple, low-relevance parameter choice completion. This is - * never used as a general-purpose completion in Java code, as it cannot - * render itself. - */ - private static class SimpleCompletion extends BasicCompletion - implements JavaSourceCompletion { - - private Icon ICON = new EmptyIcon(16); - - public SimpleCompletion(CompletionProvider provider, String text) { - super(provider, text); - setRelevance(-1); - } - - @Override - public Icon getIcon() { - return ICON; - } - - public void rendererText(Graphics g, int x, int y, boolean selected) { - // Never called - } - - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/Util.java b/src/main/java/org/fife/rsta/ac/bsh/Util.java deleted file mode 100644 index d6971660..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/Util.java +++ /dev/null @@ -1,728 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.StringReader; -import java.text.CharacterIterator; -import java.text.StringCharacterIterator; -import java.util.ArrayList; -import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.fife.rsta.ac.bsh.buildpath.SourceLocation; -import org.fife.rsta.ac.bsh.classreader.ClassFile; -import org.fife.rsta.ac.bsh.rjc.ast.CompilationUnit; - - -/** - * Utility methods for Java completion. - * - * @author Robert Futrell - * @version 1.0 - */ -public class Util { - - /** - * Optional leading text for doc comment lines (except the first line) that - * should be removed if it exists. - */ - static final Pattern DOC_COMMENT_LINE_HEADER = - Pattern.compile("\\s*\\n\\s*\\*");//^\\s*\\*\\s*[/]?"); - - /** - * Pattern matching a link in a "@link" tag. This should - * match the following: - * - *

      - *
    • ClassName
    • - *
    • fully.qualified.ClassName
    • - *
    • #method
    • - *
    • #method(int, int)
    • - *
    • String#method
    • - *
    • String#method(params)
    • - *
    • fully.qualified.ClassName#method
    • - *
    • fully.qualified.ClassName#method(params)
    • - *
    - * - * Hyperlinks ("<a href=...") are not matched and should be - * handled separately. - */ - static final Pattern LINK_TAG_MEMBER_PATTERN = - Pattern.compile("(?:\\w+\\.)*\\w+(?:#\\w+(?:\\([^\\)]*\\))?)?|" + - "#\\w+(?:\\([^\\)]*\\))?"); - - /** - * A cache of the last {@link CompilationUnit} read from some attached - * source on disk. This is cached because, in some scenarios, the method - * {@link #getCompilationUnitFromDisk(File, ClassFile)} will be called for - * the same class many times in a row (such as to get method parameter - * info for all methods in a single class). - */ - private static CompilationUnit lastCUFromDisk; - - private static SourceLocation lastCUFileParam; - private static ClassFile lastCUClassFileParam; - - - /** - * Private constructor to prevent instantiation. - */ - private Util() { - } - - - private static final void appendDocCommentTail(StringBuilder sb, - StringBuilder tail) { - - StringBuilder params = null; - StringBuilder returns = null; - StringBuilder throwsItems = null; - StringBuilder see = null; - StringBuilder seeTemp = null; - StringBuilder since = null; - StringBuilder author = null; - StringBuilder version = null; - StringBuilder unknowns = null; - boolean inParams = false, inThrows = false, - inReturns = false, inSeeAlso = false, - inSince = false, inAuthor = false, - inVersion = false, inUnknowns = false; - - String[] st = tail.toString().split("[ \t\r\n\f]+"); - String token = null; - - int i = 0; - while (iParameters:

    "); - } - else { - params.append("
    "); - } - params.append("").append(token).append(" "); - inSeeAlso=false; - inParams = true; - inReturns = false; - inThrows = false; - inSince = false; - inAuthor = false; - inVersion = false; - inUnknowns = false; - } - else if ("@return".equals(token) && iReturns:

    "); - } - inSeeAlso=false; - inReturns = true; - inParams = false; - inThrows = false; - inSince = false; - inAuthor = false; - inVersion = false; - inUnknowns = false; - } - else if ("@see".equals(token) && iSee Also:

    "); - seeTemp = new StringBuilder(); - } - else { - if (seeTemp.length()>0) { - String temp = seeTemp.substring(0, seeTemp.length()-1); - //syntax is exactly the same as link - appendLinkTagText(see, temp); - } - see.append("
    "); - seeTemp.setLength(0); - //see.append("
    "); - } - inSeeAlso = true; - inReturns = false; - inParams = false; - inThrows = false; - inSince = false; - inAuthor = false; - inVersion = false; - inUnknowns = false; - } - else if (("@throws".equals(token)) || - ("@exception".equals(token)) && iThrows:

    "); - } - else { - throwsItems.append("
    "); - } - throwsItems.append("").append(token).append(" "); - inSeeAlso = false; - inParams = false; - inReturns = false; - inThrows = true; - inSince = false; - inAuthor = false; - inVersion = false; - inUnknowns = false; - } - else if ("@since".equals(token) && iSince:

    "); - } - inSeeAlso=false; - inReturns = false; - inParams = false; - inThrows = false; - inSince = true; - inAuthor = false; - inVersion = false; - inUnknowns = false; - } - else if ("@author".equals(token) && iAuthor:

    "); - } - else { - author.append("
    "); - } - inSeeAlso=false; - inReturns = false; - inParams = false; - inThrows = false; - inSince = false; - inAuthor = true; - inVersion = false; - inUnknowns = false; - } - else if ("@version".equals(token) && iVersion:

    "); - } - else { - version.append("
    "); - } - inSeeAlso=false; - inReturns = false; - inParams = false; - inThrows = false; - inSince = false; - inAuthor = false; - inVersion = true; - inUnknowns = false; - } - else if (token.startsWith("@") && token.length()>1) { - if (unknowns==null) { - unknowns = new StringBuilder(); - } - else { - unknowns.append("

    "); - } - unknowns.append("").append(token).append("

    "); - // Stop everything; unknown/unsupported tag - inSeeAlso = false; - inParams = false; - inReturns = false; - inThrows = false; - inSince = false; - inAuthor = false; - inVersion = false; - inUnknowns = true; - } - else if (inParams) { - params.append(token).append(' '); - } - else if (inReturns) { - returns.append(token).append(' '); - } - else if (inSeeAlso) { - //see.append(token).append(' '); - seeTemp.append(token).append(' '); - } - else if (inThrows) { - throwsItems.append(token).append(' '); - } - else if (inSince) { - since.append(token).append(' '); - } - else if (inAuthor) { - author.append(token).append(' '); - } - else if (inVersion) { - version.append(token).append(' '); - } - else if (inUnknowns) { - unknowns.append(token).append(' '); - } - } - - sb.append("

    "); - - if (params!=null) { - sb.append(params).append("

    "); - } - if (returns!=null) { - sb.append(returns).append("

    "); - } - if (throwsItems!=null) { - sb.append(throwsItems).append("

    "); - } - if (see!=null) { - if (seeTemp.length()>0) { // Last @see contents - String temp = seeTemp.substring(0, seeTemp.length()-1); - //syntax is exactly the same as link - appendLinkTagText(see, temp); - } - see.append("
    "); - sb.append(see).append("

    "); - } - if (author!=null) { - sb.append(author).append("

    "); - } - if (version!=null) { - sb.append(version).append("

    "); - } - if (since!=null) { - sb.append(since).append("

    "); - } - if (unknowns!=null) { - sb.append(unknowns).append("

    "); - } - - } - - - /** - * Appends HTML representing a "link" or "linkplain" Javadoc element to - * a string buffer.

    - * For some information on this format, see - * - * http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#see. - * - * @param appendTo The buffer to append to. - * @param linkContent The content of a "link", "linkplain" or "see" item. - */ - private static final void appendLinkTagText(StringBuilder appendTo, - String linkContent) { - linkContent = linkContent.trim(); // If "@link" and text on different lines - Matcher m = LINK_TAG_MEMBER_PATTERN.matcher(linkContent); - - if (m.find() && m.start() == 0) { - - appendTo.append("0) { // Not -1 - String prefix = match.substring(0, pound); - if ("java.lang.Object".equals(prefix)) { - text = match.substring(pound+1); - } - } - else { // Just use whole match (invalid link?) - // TODO: Could be just a class name. Find on classpath - text = match; - } - } - else { // match.length() < linkContent.length() - int offs = match.length(); - // Will usually skip just a single space - while (offs").append(text); - appendTo.append(""); - - } - - // @see - * This is a - * pre block - * - * @param dc The documentation comment. - * @return An HTML version of the comment. - */ - public static final String docCommentToHtml(String dc) { - - if (dc==null) { - return null; - } - if (dc.endsWith("*/")) { - dc = dc.substring(0, dc.length()-2); - } - - // First, strip the line transitions. These always seem to be stripped - // first from Javadoc, even when in between

     and 
    tags. - Matcher m = DOC_COMMENT_LINE_HEADER.matcher(dc); - dc = m.replaceAll("\n"); - - StringBuilder html = new StringBuilder( - ""); - StringBuilder tailBuf = null; - - BufferedReader r = new BufferedReader(new StringReader(dc)); - - try { - - // Handle the first line (guaranteed to be at least 1 line). - String line = r.readLine().substring(3); - line = possiblyStripDocCommentTail(line); - int offs = 0; - while (offs') { - result.append(">"); - } - else if (character == '\"') { - result.append("""); - } - else if (character == '\'') { - result.append("'"); - } - else if (character == '&') { - result.append("&"); - } - else { - //the char is not a special one - //add it to the result as is - result.append(character); - } - character = iterator.next(); - } - return result.toString(); - } - - - private static final StringBuilder fixDocComment(StringBuilder text) { - - // Nothing to do. - int index = text.indexOf("{@"); - if (index==-1) { - return text; - } - - StringBuilder sb = new StringBuilder(); - int textOffs = 0; - - do { - - int closingBrace = indexOf('}', text, index+2); - if (closingBrace>-1) { // Should practically always be true - - sb.append(text, textOffs, index); - String content = text.substring(index+2, closingBrace); - index = textOffs = closingBrace + 1; - - if (content.startsWith("code ")) { - sb.append(""). - append(forXML(content.substring(5))). - append(""); - } - - else if (content.startsWith("link ")) { - sb.append(""); - appendLinkTagText(sb, content.substring(5)); - sb.append(""); - } - - else if (content.startsWith("linkplain ")) { - appendLinkTagText(sb, content.substring(10)); - } - - else if (content.startsWith("literal ")) { - // TODO: Should escape HTML-breaking chars, such as '>'. - sb.append(content.substring(8)); - } - - else { // Unhandled Javadoc tag - sb.append("").append(content).append(""); - } - - } - else { - break; // Unclosed javadoc tag - just bail - } - - } while ((index=text.indexOf("{@", index))>-1); - - if (textOffsnull if it is not found - * or an IO error occurs. - */ - public static CompilationUnit getCompilationUnitFromDisk( - SourceLocation loc, ClassFile cf) { - - // Cached value? - if (loc==lastCUFileParam && cf==lastCUClassFileParam) { - //System.out.println("Returning cached CompilationUnit"); - return lastCUFromDisk; - } - - lastCUFileParam = loc; - lastCUClassFileParam = cf; - CompilationUnit cu = null; - - if(loc != null) { - try { - cu = loc.getCompilationUnit(cf); - } catch (IOException ioe) { - ioe.printStackTrace(); - } - } - - lastCUFromDisk = cu; - return cu; - - } - - - /** - * Returns the "unqualified" version of a (possibly) fully-qualified - * class name. - * - * @param clazz The class name. - * @return The unqualified version of the name. - */ - public static final String getUnqualified(String clazz) { - int dot = clazz.lastIndexOf('.'); - if (dot>-1) { - clazz = clazz.substring(dot+1); - } - return clazz; - } - - - /** - * Returns the next location of a single character in a character sequence. - * This method is here because StringBuilder doesn't get this - * method added to it until Java 1.5. - * - * @param ch The character to look for. - * @param sb The character sequence. - * @param offs The offset at which to start looking. - * @return The next location of the character, or -1 if it is not - * found. - */ - private static final int indexOf(char ch, CharSequence sb, int offs) { - while (offs.' character. - * - * @param str The string to check. - * @return Whether the string is fully qualified. - * @see #getUnqualified(String) - */ - public static final boolean isFullyQualified(String str) { - return str.indexOf('.')>-1; - } - - - /** - * Returns whether this line ends in the middle of a pre-block. - * - * @param line The line's contents. - * @param prevValue Whether this line started in a pre-block. - * @return Whether the line ends in a pre-block. - */ - private static final boolean isInPreBlock(String line, boolean prevValue) { - int lastPre = line.lastIndexOf("pre>"); - if (lastPre<=0) { - return prevValue; - } - char prevChar = line.charAt(lastPre-1); - if (prevChar=='<') { - return true; - } - else if (prevChar=='/' && lastPre>=2) { - if (line.charAt(lastPre-2)=='<') { - return false; - } - } - return prevValue; - } - - - /** - * Removes the tail end of a documentation comment from a string, if it - * exists. - * - * @param str The string. - * @return The string, possibly with the documentation comment tail - * removed. - */ - private static final String possiblyStripDocCommentTail(String str) { - if (str.endsWith("*/")) { - str = str.substring(0, str.length()-2); - } - return str; - } - - - /** - * A faster way to split on a single char than String#split(), since - * we'll be doing this in a tight loop possibly thousands of times (rt.jar). - * This is also fundamentally different than {@link String#split(String)}), - * in the case where str ends with ch - this - * method will return an empty item at the end of the returned array, while - * String#split() will not. - * - * @param str The string to split. - * @param ch The char to split on. - * @return The string, split on the character (e.g. '/' or - * '.'). - */ - public static final String[] splitOnChar(String str, int ch) { - List list = new ArrayList(3); - int pos = 0; - int old = 0; - while ((pos=str.indexOf(ch, old))>-1) { - list.add(str.substring(old, pos)); - old = pos+1; - } - // If str ends in ch, this adds an empty item to the end of the list. - // This is what we want. - list.add(str.substring(old)); - String[] array = new String[list.size()]; - return list.toArray(array); - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/buildpath/ClassEnumerationReader.java b/src/main/java/org/fife/rsta/ac/bsh/buildpath/ClassEnumerationReader.java deleted file mode 100644 index 648fa65b..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/buildpath/ClassEnumerationReader.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * 04/21/2012 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.buildpath; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.List; - - -/** - * Reads plain text files enumerating classes to take from the classpath and - * add to a {@link ClasspathLibraryInfo}. Files should have a format similar - * to the following: - * - *
    - * - com.mycompany.pkg1.Class1
    - * Class2
    - * Class3
    - * - com.mycompany.pkg2.Foo
    - * Bar
    - * - aonther.pkg.Utils
    - * ...
    - * 
    - * - * Such files are expected to be UTF-8. The exact file structure is as follows: - *
      - *
    • Lines that start with a "-" denote a fully-qualified - * class, interface, or enum name. - *
    • Lines following a line starting with "-" are simply a - * class, interface, or enum name, and are assumed to be in the same - * package as the previous class on the "-" line. - *
    • Blank lines and lines starting with "#" are ignored. - *
    - * - * @author Robert Futrell - * @version 1.0 - */ -public class ClassEnumerationReader { - - - /** - * Private constructor to prevent instantiation. - */ - private ClassEnumerationReader() { - } - - - /** - * Returns the list of classes specified in the given stream. - * - * @param in The input stream to read from. This will be closed when - * this method returns. - * @return The list of class names read. - * @throws IOException If an IO error occurs. - */ - public static List getClassNames(InputStream in) throws IOException { - - String lastPkg = null; - String line = null; - List classNames = new ArrayList(); - - BufferedReader r = new BufferedReader(new InputStreamReader(in, "UTF-8")); - try { - - while ((line=r.readLine())!=null) { - - // Skip blank lines and comments - line = line.trim(); - if (line.length()==0 || line.charAt(0)=='#') { - continue; - } - - // A new fully-qualified class name - if (line.charAt(0)=='-') { - line = line.substring(1).trim(); - classNames.add(line); - int lastDot = line.lastIndexOf('.'); - lastPkg = line.substring(0, lastDot+1); - } - - // Just a class name - else { - String className = line; - if (lastPkg!=null) { - className = lastPkg + className; - } - classNames.add(className); - } - - } - - } finally { - r.close(); - } - - return classNames; - - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/buildpath/ClasspathLibraryInfo.java b/src/main/java/org/fife/rsta/ac/bsh/buildpath/ClasspathLibraryInfo.java deleted file mode 100644 index 0ae8335f..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/buildpath/ClasspathLibraryInfo.java +++ /dev/null @@ -1,220 +0,0 @@ -/* - * 04/21/2012 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.buildpath; - -import java.io.BufferedInputStream; -import java.io.DataInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.fife.rsta.ac.bsh.PackageMapNode; -import org.fife.rsta.ac.bsh.classreader.ClassFile; - - -/** - * Information about specific classes on the current application's classpath to - * add to the "build path." This type of container is useful if your - * application ships with specific classes you want included in code - * completion, but you don't want to add the entire jar to the build path.

    - * - * Since there is no real way to determine all classes in a package via - * reflection, you must explicitly enumerate all classes that are on the - * classpath that you want on the build path. To make this easier, you can - * use the {@link ClassEnumerationReader} class to read a list of classes from - * a plain text file or other resource.

    - * - * If you're delivering the corresponding .java source files also on the - * classpath (i.e. you have a library "hard-coded" to be on the build path), - * you can set the source location to be a ClasspathSourceLocation - * to get the source located automatically. - * - * @author Robert Futrell - * @version 1.0 - * @see JarLibraryInfo - * @see DirLibraryInfo - * @see ClasspathSourceLocation - */ -public class ClasspathLibraryInfo extends LibraryInfo { - - /** - * Mapping of class names to ClassFiles. This information is - * cached even though it's also cached at the JarReader level - * because the class definitions are effectively immutable since they're - * on the classpath. This allows you to theoretically share a single - * ClasspathLibraryInfo across several different jar managers. - */ - private Map classNameToClassFile; - - - /** - * Constructor. - * - * @param classes A list of fully-qualified class names for classes you - * want added to the build path. - */ - public ClasspathLibraryInfo(String[] classes) { - this(Arrays.asList(classes), null); - } - - - /** - * Constructor. - * - * @param classes A list of fully-qualified class names for classes you - * want added to the build path. - */ - public ClasspathLibraryInfo(List classes) { - this(classes, null); - } - - - /** - * Constructor. - * - * @param classes A list of fully-qualified class names for classes you - * want added to the build path. - * @param sourceLoc The location of the source files for the classes given. - * This may be null. - */ - public ClasspathLibraryInfo(List classes, SourceLocation sourceLoc){ - setSourceLocation(sourceLoc); - classNameToClassFile = new HashMap(); - int count = classes==null ? 0 : classes.size(); - for (int i=0; i0. - * - * @return 0 always. - */ - @Override - public long getLastModified() { - return 0; - } - - - @Override - public String getLocationAsString() { - return null; - } - - - @Override - public int hashCode() { - return classNameToClassFile.hashCode(); - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/buildpath/ClasspathSourceLocation.java b/src/main/java/org/fife/rsta/ac/bsh/buildpath/ClasspathSourceLocation.java deleted file mode 100644 index e844a36c..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/buildpath/ClasspathSourceLocation.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 04/21/2012 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.buildpath; - -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; - -import org.fife.rsta.ac.bsh.classreader.ClassFile; -import org.fife.rsta.ac.bsh.rjc.ast.CompilationUnit; -import org.fife.rsta.ac.bsh.rjc.lexer.Scanner; -import org.fife.rsta.ac.bsh.rjc.parser.ASTFactory; - - -/** - * Represents Java source files somewhere on the classpath. This might be - * somewhat of a unique situation, since often source isn't on the classpath, - * only class files are. However, there may be times when you want to ship - * both the classes and source for a library and put them on your classpath - * for simplicity of integrating with this code completion library. In such a - * case, you would use a ClasspathLibraryInfo and use this class - * for the source location.

    - * - * This class has no state; any classes it's asked about, it assumes it can - * find the corresponding .java file somewhere on the classpath using the - * class's ClassLoader. - * - * @author Robert Futrell - * @version 1.0 - * @see ClasspathLibraryInfo - */ -public class ClasspathSourceLocation implements SourceLocation { - - - /** - * {@inheritDoc} - */ - public CompilationUnit getCompilationUnit(ClassFile cf) throws IOException { - - CompilationUnit cu = null; - - String res = cf.getClassName(true).replace('.', '/') + ".java"; - InputStream in = getClass().getClassLoader().getResourceAsStream(res); - if (in!=null) { - Scanner s = new Scanner(new InputStreamReader(in)); - cu = new ASTFactory().getCompilationUnit(res, s); - } - - return cu; - - } - - - /** - * {@inheritDoc} - */ - public String getLocationAsString() { - return null; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/buildpath/DirLibraryInfo.java b/src/main/java/org/fife/rsta/ac/bsh/buildpath/DirLibraryInfo.java deleted file mode 100644 index e8cb4671..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/buildpath/DirLibraryInfo.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * 04/21/2012 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.buildpath; - -import java.io.File; -import java.io.IOException; - -import org.fife.rsta.ac.bsh.PackageMapNode; -import org.fife.rsta.ac.bsh.classreader.ClassFile; - - -/** - * Information about a folder containing a set of classes to add to the "build - * path." This type of library info could be used, for example, to add sibling - * projects in a workspace, not yet built into jars, to another project's build - * path. - * - * @author Robert Futrell - * @version 1.0 - * @see JarLibraryInfo - * @see ClasspathLibraryInfo - */ -public class DirLibraryInfo extends LibraryInfo { - - private File dir; - - - public DirLibraryInfo(File dir) { - this(dir, null); - } - - - public DirLibraryInfo(String dir) { - this(new File(dir)); - } - - - public DirLibraryInfo(File dir, SourceLocation sourceLoc) { - setDirectory(dir); - setSourceLocation(sourceLoc); - } - - - public DirLibraryInfo(String dir, SourceLocation sourceLoc) { - this(new File(dir), sourceLoc); - } - - - @Override - public void bulkClassFileCreationEnd() { - // Do nothing - } - - - @Override - public void bulkClassFileCreationStart() { - // Do nothing - } - - - /** - * Compares this LibraryInfo to another one. Two instances of - * this class are only considered equal if they represent the same class - * file location. Source attachment is irrelevant. - * - * @return The sort order of these two library infos. - */ - public int compareTo(LibraryInfo info) { - if (info==this) { - return 0; - } - int result = -1; - if (info instanceof DirLibraryInfo) { - return dir.compareTo(((DirLibraryInfo)info).dir); - } - return result; - } - - - @Override - public ClassFile createClassFile(String entryName) throws IOException { - return createClassFileBulk(entryName); - } - - - @Override - public ClassFile createClassFileBulk(String entryName) throws IOException { - File file = new File(dir, entryName); - if (!file.isFile()) { - System.err.println("ERROR: Invalid class file: " + file.getAbsolutePath()); - return null; - } - return new ClassFile(file); - } - - - @Override - public PackageMapNode createPackageMap() throws IOException { - PackageMapNode root = new PackageMapNode(); - getPackageMapImpl(dir, null, root); - return root; - } - - - @Override - public long getLastModified() { - return dir.lastModified(); - } - - - @Override - public String getLocationAsString() { - return dir.getAbsolutePath(); - } - - - /** - * Does the dirty-work of finding all class files in a directory tree. - * - * @param dir The directory to scan. - * @param pkg The package name scanned so far, in the form - * "com/company/pkgname"... - * @throws IOException If an IO error occurs. - */ - private void getPackageMapImpl(File dir, String pkg, PackageMapNode root) - throws IOException { - - File[] children = dir.listFiles(); - - for (int i=0; inull. - */ - private void setDirectory(File dir) { - if (dir==null || !dir.isDirectory()) { - String name = dir==null ? "null" : dir.getAbsolutePath(); - throw new IllegalArgumentException("Directory does not exist: " + name); - } - this.dir = dir; - } - - - /** - * Returns a string representation of this jar information. Useful for - * debugging. - * - * @return A string representation of this object. - */ - @Override - public String toString() { - return "[DirLibraryInfo: " + - "jar=" + dir.getAbsolutePath() + - "; source=" + getSourceLocation() + - "]"; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/buildpath/DirSourceLocation.java b/src/main/java/org/fife/rsta/ac/bsh/buildpath/DirSourceLocation.java deleted file mode 100644 index 1940b041..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/buildpath/DirSourceLocation.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * 04/21/2012 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.buildpath; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; - -import org.fife.rsta.ac.bsh.classreader.ClassFile; -import org.fife.rsta.ac.bsh.rjc.ast.CompilationUnit; -import org.fife.rsta.ac.bsh.rjc.lexer.Scanner; -import org.fife.rsta.ac.bsh.rjc.parser.ASTFactory; - - -/** - * Represents Java source in a directory, such as in a project's source folder. - * - * @author Robert Futrell - * @version 1.0 - */ -public class DirSourceLocation implements SourceLocation { - - private File dir; - - - /** - * Constructor. - * - * @param dir The directory containing the source files. - */ - public DirSourceLocation(String dir) { - this(new File(dir)); - } - - - /** - * Constructor. - * - * @param dir The directory containing the source files. - */ - public DirSourceLocation(File dir) { - this.dir = dir; - } - - - /** - * {@inheritDoc} - */ - public CompilationUnit getCompilationUnit(ClassFile cf) throws IOException { - - CompilationUnit cu = null; - - String entryName = cf.getClassName(true); - entryName = entryName.replace('.', '/'); - entryName += ".java"; - //System.out.println("DEBUG: entry name: " + entryName); - File file = new File(dir, entryName); - if (!file.isFile()) { - // Be nice and check for "src/" subdirectory - file = new File(dir, "src/" + entryName); - } - - if (file.isFile()) { - BufferedReader r = new BufferedReader(new FileReader(file)); - try { - Scanner s = new Scanner(r); - cu = new ASTFactory().getCompilationUnit(entryName, s); - //System.out.println("DEBUG: cu: " + cu); - } finally { - r.close(); - } - } - - return cu; - - } - - - /** - * {@inheritDoc} - */ - public String getLocationAsString() { - return dir.getAbsolutePath(); - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/buildpath/JarLibraryInfo.java b/src/main/java/org/fife/rsta/ac/bsh/buildpath/JarLibraryInfo.java deleted file mode 100644 index a577746c..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/buildpath/JarLibraryInfo.java +++ /dev/null @@ -1,214 +0,0 @@ -/* - * 04/21/2012 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.buildpath; - -import java.io.BufferedInputStream; -import java.io.DataInputStream; -import java.io.File; -import java.io.IOException; -import java.util.Enumeration; -import java.util.jar.JarEntry; -import java.util.jar.JarFile; -import java.util.zip.ZipEntry; - -import org.fife.rsta.ac.bsh.PackageMapNode; -import org.fife.rsta.ac.bsh.classreader.ClassFile; - - -/** - * Information about a jar of classes to add to the "build path." - * - * @author Robert Futrell - * @version 1.0 - * @see DirLibraryInfo - * @see ClasspathLibraryInfo - */ -public class JarLibraryInfo extends LibraryInfo { - - private File jarFile; - private JarFile bulkCreateJar; - - - public JarLibraryInfo(String jarFile) { - this(new File(jarFile)); - } - - - public JarLibraryInfo(File jarFile) { - this(jarFile, null); - } - - - public JarLibraryInfo(File jarFile, SourceLocation sourceLoc) { - setJarFile(jarFile); - setSourceLocation(sourceLoc); - } - - - @Override - public void bulkClassFileCreationEnd() { - try { - bulkCreateJar.close(); - } catch (IOException ioe) { - ioe.printStackTrace(); - } - } - - - @Override - public void bulkClassFileCreationStart() { - try { - bulkCreateJar = new JarFile(jarFile); - } catch (IOException ioe) { - ioe.printStackTrace(); - } - } - - - /** - * Compares this LibraryInfo to another one. Two instances of - * this class are only considered equal if they represent the same class - * file location. Source attachment is irrelevant. - * - * @return The sort order of these two library infos. - */ - public int compareTo(LibraryInfo info) { - if (info==this) { - return 0; - } - int result = -1; - if (info instanceof JarLibraryInfo) { - result = jarFile.compareTo(((JarLibraryInfo)info).jarFile); - } - return result; - } - - - @Override - public ClassFile createClassFile(String entryName) throws IOException { - JarFile jar = new JarFile(jarFile); - try { - return createClassFileImpl(jar, entryName); - } finally { - jar.close(); - } - } - - - @Override - public ClassFile createClassFileBulk(String entryName) throws IOException { - return createClassFileImpl(bulkCreateJar, entryName); - } - - - private static final ClassFile createClassFileImpl(JarFile jar, - String entryName) throws IOException { - JarEntry entry = (JarEntry)jar.getEntry(entryName); - if (entry==null) { - System.err.println("ERROR: Invalid entry: " + entryName); - return null; - } - DataInputStream in = new DataInputStream( - new BufferedInputStream(jar.getInputStream(entry))); - ClassFile cf = null; - try { - cf = new ClassFile(in); - } finally { - in.close(); - } - return cf; - } - - - @Override - public PackageMapNode createPackageMap() throws IOException { - - PackageMapNode root = new PackageMapNode(); - JarFile jar = new JarFile(jarFile); - - try { - - Enumeration e = jar.entries(); - while (e.hasMoreElements()) { - ZipEntry entry = e.nextElement(); - String entryName = entry.getName(); - if (entryName.endsWith(".class")) { - root.add(entryName); - } - } - - } finally { - jar.close(); - } - - return root; - - } - - - @Override - public long getLastModified() { - return jarFile.lastModified(); - } - - - @Override - public String getLocationAsString() { - return jarFile.getAbsolutePath(); - } - - - /** - * Returns the jar file this instance is wrapping. - * - * @return The jar file. - */ - public File getJarFile() { - return jarFile; - } - - - @Override - public int hashCode() { - return jarFile.hashCode(); - } - - - /** - * Sets the jar file location. - * - * @param jarFile The jar file location. This cannot be null. - */ - private void setJarFile(File jarFile) { - if (jarFile==null || !jarFile.exists()) { - String name = jarFile==null ? "null" : jarFile.getAbsolutePath(); - throw new IllegalArgumentException("Jar does not exist: " + name); - } - this.jarFile = jarFile; - } - - - /** - * Returns a string representation of this jar information. Useful for - * debugging. - * - * @return A string representation of this object. - */ - @Override - public String toString() { - return "[JarLibraryInfo: " + - "jar=" + jarFile.getAbsolutePath() + - "; source=" + getSourceLocation() + - "]"; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/buildpath/LibraryInfo.java b/src/main/java/org/fife/rsta/ac/bsh/buildpath/LibraryInfo.java deleted file mode 100644 index e11b4ba7..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/buildpath/LibraryInfo.java +++ /dev/null @@ -1,283 +0,0 @@ -/* - * 04/21/2012 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.buildpath; - -import java.io.File; -import java.io.IOException; - -import org.fife.rsta.ac.bsh.PackageMapNode; -import org.fife.rsta.ac.bsh.classreader.ClassFile; - - -/** - * Information about a jar, compiled class folder, or other source of classes - * to add to the "build path" for Java completion. Instances of this class are - * added to a {@link JarManager} for each library that should be on the build - * path.

    - * - * This class also keeps track of an optional source location, such as a zip - * file or source folder. If defined, this location is used to find the .java - * source corresponding to the library's classes, which is used to display - * Javadoc comments during code completion. - * - * @author Robert Futrell - * @version 1.0 - * @see DirLibraryInfo - * @see JarLibraryInfo - * @see ClasspathLibraryInfo - */ -public abstract class LibraryInfo implements Comparable, - Cloneable { - - /** - * The location of the source files corresponding to this library. This - * may be null. - */ - private SourceLocation sourceLoc; - - - /** - * Does any cleanup necessary after a call to - * {@link #bulkClassFileCreationStart()}. - * - * @throws IOException If an IO error occurs. - * @see #bulkClassFileCreationStart() - * @see #createClassFileBulk(String) - */ - public abstract void bulkClassFileCreationEnd() throws IOException; - - - /** - * Readies this library for many class files being fetched via - * {@link #createClassFileBulk(String)}. After calling this method, - * the actual class file fetching should be done in a try/finally block - * that ensures a call to {@link #bulkClassFileCreationEnd()}; e.g. - * - *

    -	 * libInfo.bulkClassFileCreationStart();
    -	 * try {
    -	 *    String entryName = ...;
    -	 *    ClassFile cf = createClassFileBulk(entryName);
    -	 *    ...
    -	 * } finally {
    -	 *    libInfo.bulkClassFileCreationEnd();
    -	 * }
    -	 * 
    - * - * @throws IOException If an IO error occurs. - * @see #bulkClassFileCreationEnd() - * @see #createClassFileBulk(String) - */ - public abstract void bulkClassFileCreationStart() throws IOException; - - - /** - * Returns a deep copy of this library. - * - * @return A deep copy. - */ - @Override - public Object clone() { - try { - return super.clone(); - } catch (CloneNotSupportedException cnse) { // Never happens - throw new IllegalStateException( - "Doesn't support cloning, but should! - " + getClass().getName()); - } - } - - - /** - * Returns the class file information for the specified class. Instances - * of JarReader can call this method to lazily load - * information on individual classes and shove it into their package maps. - *

    - * If many class files will be fetched at a time, you should prefer using - * {@link #bulkClassFileCreationStart()} and - * {@link #createClassFileBulk(String)} over this method, for performance - * reasons. - * - * @param entryName The fully qualified name of the class file. - * @return The class file, or null if it isn't found in this - * library. - * @throws IOException If an IO error occurs. - * @see #createClassFileBulk(String) - */ - public abstract ClassFile createClassFile(String entryName) throws IOException; - - - /** - * Returns the class file information for the specified class. Instances - * of JarReader can call this method to lazily load - * information on individual classes and shove it into their package maps. - *

    - * This method should be used when multiple classes will be fetched from - * this library at the same time. It should only be called after a call to - * {@link #bulkClassFileCreationStart()}. If only a single class file is - * being fetched, it is simpler to call {@link #createClassFile(String)}. - * - * @param entryName The fully qualified name of the class file. - * @return The class file, or null if it isn't found in this - * library. - * @throws IOException If an IO error occurs. - * @see #createClassFile(String) - */ - public abstract ClassFile createClassFileBulk(String entryName) - throws IOException; - - - /** - * Creates and returns a map of maps representing the hierarchical package - * structure in this library. - * - * @return The package structure in this library. - * @throws IOException If an IO error occurs. - */ - public abstract PackageMapNode createPackageMap() throws IOException; - - - /** - * Two LibraryInfos are considered equal if they represent - * the same class file location. Source attachment is irrelevant. - * - * @return Whether the specified instance represents the same class - * source as this one. - */ - @Override - public boolean equals(Object o) { - return o instanceof LibraryInfo && - compareTo((LibraryInfo)o)==0; - } - - - /** - * Returns information on the "main" jar for a JRE. This will be - * rt.jar everywhere except OS X, where it will be - * classes.jar. The associated source zip/jar file is also - * checked for. - * - * @return The information, or null if there is not a JRE in - * the specified directory. - * @see #getMainJreJarInfo() - */ - public static LibraryInfo getJreJarInfo(File jreHome) { - - LibraryInfo info = null; - - File mainJar = new File(jreHome, "lib/rt.jar"); // Sun JRE's - File sourceZip = null; - - if (mainJar.isFile()) { // Sun JRE's - sourceZip = new File(jreHome, "src.zip"); - if (!sourceZip.isFile()) { - // Might be a JRE inside a JDK - sourceZip = new File(jreHome, "../src.zip"); - } - } - - else { // Might be OS X - mainJar = new File(jreHome, "../Classes/classes.jar"); - // ${java.home}/src.jar is the common location on OS X. - sourceZip = new File(jreHome, "src.jar"); - } - - if (mainJar.isFile()) { - info = new JarLibraryInfo(mainJar); - if (sourceZip.isFile()) { // Make sure our last guess actually exists - info.setSourceLocation(new ZipSourceLocation(sourceZip)); - } - } - else { - System.err.println("[ERROR]: Cannot locate JRE jar in " + - jreHome.getAbsolutePath()); - mainJar = null; - } - - return info; - - } - - - /** - * Returns the time this library was last modified. For jar files, this - * would be the modified date of the file. For directories, this would be - * the time a file in the directory was most recently modified. This - * information is used to determine whether callers should clear their - * cached package map information and load it anew.

    - * - * This API may change in the future. - * - * @return The last time this library was modified. - */ - public abstract long getLastModified(); - - - /** - * Returns the location of this library, as a string. If this library - * is contained in a single jar file, this will be the full path to that - * jar. If it is a directory containing classes, it will be the full path - * of the directory. Otherwise, this value will be null. - * - * @return The location of this library. - */ - public abstract String getLocationAsString(); - - - /** - * Returns information on the JRE running this application. This will be - * rt.jar everywhere except OS X, where it will be - * classes.jar. The associated source zip/jar file is also - * checked for. - * - * @return The information, or null if an error occurs. - * @see #getJreJarInfo(File) - */ - public static LibraryInfo getMainJreJarInfo() { - String javaHome = System.getProperty("java.home"); - return getJreJarInfo(new File(javaHome)); - } - - - /** - * Returns the location of the source corresponding to this library. - * - * @return The source for this library, or null if none. - * @see #setSourceLocation(SourceLocation) - */ - public SourceLocation getSourceLocation() { - return sourceLoc; - } - - - /** - * Subclasses should override this method since {@link #equals(Object)} is - * overridden. Instances of LibraryInfo aren't typically - * stored in maps, so the hash value isn't necessarily important to - * RSTALanguageSupport. - * - * @return The hash code for this library. - */ - @Override - public abstract int hashCode(); - - - /** - * Sets the location of the source corresponding to this library. - * - * @param sourceLoc The source location. This may be null. - * @see #getSourceLocation() - */ - public void setSourceLocation(SourceLocation sourceLoc) { - this.sourceLoc = sourceLoc; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/buildpath/SourceLocation.java b/src/main/java/org/fife/rsta/ac/bsh/buildpath/SourceLocation.java deleted file mode 100644 index 7c6255ef..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/buildpath/SourceLocation.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 04/21/2012 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.buildpath; - -import java.io.IOException; - -import org.fife.rsta.ac.bsh.classreader.ClassFile; -import org.fife.rsta.ac.bsh.rjc.ast.CompilationUnit; - - -/** - * Represents the location of Java source, either in a zip file (src.zip), - * a flat file (source in a project's source folder), or in some other location. - * - * @author Robert Futrell - * @version 1.0 - * @see DirSourceLocation - * @see ZipSourceLocation - * @see ClasspathSourceLocation - */ -public interface SourceLocation { - - - /** - * Returns an AST for the specified class file. - * - * @param cf The class file to grab the AST for. - * @return The AST, or null if it cannot be found. - * @throws IOException If an IO error occurs. - */ - CompilationUnit getCompilationUnit(ClassFile cf) throws IOException; - - - /** - * Returns a string representation of this source location. For locations - * on disk such as zip files or directories, this should be the full path - * to the resource. - * - * @return The location of this source as a string, or null if - * it is not an accessible location. - */ - public String getLocationAsString(); - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/buildpath/ZipSourceLocation.java b/src/main/java/org/fife/rsta/ac/bsh/buildpath/ZipSourceLocation.java deleted file mode 100644 index 60b3c0ca..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/buildpath/ZipSourceLocation.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * 04/21/2012 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.buildpath; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; - -import org.fife.rsta.ac.bsh.classreader.ClassFile; -import org.fife.rsta.ac.bsh.rjc.ast.CompilationUnit; -import org.fife.rsta.ac.bsh.rjc.lexer.Scanner; -import org.fife.rsta.ac.bsh.rjc.parser.ASTFactory; - - -/** - * Represents source inside a zip or jar file. The source can be either in - * a "src/" subfolder, or at the root level of the archive. This - * class is useful for the JDK or other libraries that come with a - * src.zip file (src.jar on OS X). - * - * @author Robert Futrell - * @version 1.0 - */ -public class ZipSourceLocation implements SourceLocation { - - private File archive; - - - /** - * Constructor. - * - * @param archive The archive containing the source. This should be an - * absolute path to ensure correctness. - */ - public ZipSourceLocation(String archive) { - this(new File(archive)); - } - - - /** - * Constructor. - * - * @param archive The archive containing the source. - */ - public ZipSourceLocation(File archive) { - this.archive = archive; - } - - - /** - * {@inheritDoc} - */ - public CompilationUnit getCompilationUnit(ClassFile cf) throws IOException { - - CompilationUnit cu = null; - - ZipFile zipFile = new ZipFile(archive); - - try { - - String entryName = cf.getClassName(true).replaceAll("\\.", "/"); - entryName += ".java"; - //System.out.println("DEBUG: entry name: " + entryName); - ZipEntry entry = zipFile.getEntry(entryName); - if (entry == null) { - // Seen in some src.jar files, for example OS X's src.jar - entry = zipFile.getEntry("src/" + entryName); - } - - if (entry != null) { - InputStream in = zipFile.getInputStream(entry); - Scanner s = new Scanner(new InputStreamReader(in)); - cu = new ASTFactory().getCompilationUnit(entryName, s); - } - - } finally { - zipFile.close(); // Closes the input stream too - } - - return cu; - - } - - - /** - * {@inheritDoc} - */ - public String getLocationAsString() { - return archive.getAbsolutePath(); - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/AccessFlags.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/AccessFlags.java deleted file mode 100644 index f116668c..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/classreader/AccessFlags.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.classreader; - - -/** - * Class/interface access flag masks. - * - * @author Robert Futrell - * @version 1.0 - */ -public interface AccessFlags { - - /** - * Declared public; may be accessed from outside its package. - */ - public static final int ACC_PUBLIC = 0x0001; - - /** - * Declared private; usable only within the defining class. - */ - public static final int ACC_PRIVATE = 0x0002; - - /** - * Declared protected; may be accessed within subclasses. - */ - public static final int ACC_PROTECTED = 0x0004; - - /** - * Declared static. - */ - public static final int ACC_STATIC = 0x0008; - - /** - * Declared final; no subclasses allowed. - */ - public static final int ACC_FINAL = 0x0010; - - /** - * Treat superclass methods specially when invoked by the - * invokespecial instruction. - */ - /* - * NOTE: This is the same value as ACC_SYNCHRONIZED. - */ - public static final int ACC_SUPER = 0x0020; - - /** - * Declared synchronized; invocation is wrapped in a monitor block. - */ - /* - * NOTE: This is the same value as ACC_SUPER. - */ - public static final int ACC_SYNCHRONIZED = 0x0020; - - /** - * Declared volatile; cannot be cached. - */ - public static final int ACC_VOLATILE = 0x0040; - - /** - * Declared transient; not written or read by a persistent object manager. - */ - public static final int ACC_TRANSIENT = 0x0080; - - /** - * Declared native; implemented in a language other than Java. - */ - public static final int ACC_NATIVE = 0x0100; - - /** - * Is an interface, not a class. - */ - public static final int ACC_INTERFACE = 0x0200; - - /** - * Declared abstract; may not be instantiated. - */ - public static final int ACC_ABSTRACT = 0x0400; - - /** - * Declared strictfp; floating-point mode is FP-strict. - */ - public static final int ACC_STRICT = 0x0800; - - /** - * Declared syntheticClassFile structure. - * - * @author Robert Futrell - * @version 1.0 - */ -public class ClassFile implements AccessFlags { - - private static final boolean DEBUG = false; - - /** - * The class file's minor version number. - */ - private int minorVersion; // u2 - - /** - * The class file's major version number. - */ - private int majorVersion; // u2 - - /** - * Constant pool infos. - */ - private ConstantPoolInfo[] constantPool; // Length constant_pool_count-1 !! - - /** - * Permissions and properties of this class or interface. - */ - private int accessFlags; // u2 - - /** - * Index into {@link #constantPool} for a ConstantClassInfo - * structure representing the class or interface defined in this class file. - */ - private int thisClass; // u2 - - /** - * Index into {@link #constantPool} for a ConstantClassInfo - * structure representing the superclass of this class or interface. If - * this value is 0 then this class must be class - * java.lang.Object. If this is an interface, then this index - * must point to information about class java.lang.Object. - */ - private int superClass; // u2 - - /** - * Indices into {@code constantPool} for ConstantClassInfos - * representing the implemented interfaces of this class or interface. - */ - int[] interfaces; // u2[] - - /** - * Structures giving complete descriptions of the fields in this class - * or interface. - */ - private FieldInfo[] fields; - - /** - * Structures giving complete descriptions of the methods in this class or - * interface. - */ - private MethodInfo[] methods; - - /** - * Whether this class is deprecated. - */ - private boolean deprecated; - - /** - * Attributes of this class or interface. - */ - private AttributeInfo[] attributes; - - /** - * Parameter types, such as "String" in List<String>. - */ - private List paramTypes; - - /** - * A mapping of type parameters to type arguments. This is set via - * {@link #setTypeParamsToTypeArgs(Map)} during code completion of members of an - * instance variable whose type is represented by this class file. This - * ClassFile doesn't use this field itself; rather, it's there - * for consumers (such as the Java code completion API) to use. - */ - private Map typeMap; - - public static final String DEPRECATED = "Deprecated"; - public static final String ENCLOSING_METHOD = "EnclosingMethod"; - public static final String INNER_CLASSES = "InnerClasses"; - public static final String RUNTIME_VISIBLE_ANNOTATIONS = "RuntimeVisibleAnnotations"; - public static final String SIGNATURE = "Signature"; - public static final String SOURCE_FILE = "SourceFile"; - public static final String BOOTSTRAP_METHODS = "BootstrapMethods"; - - /** - * The 4-byte class file header, "CAFEBABE". - */ - private static final byte[] HEADER = { (byte)0xCA, (byte)0xFE, - (byte)0xBA, (byte)0xBE }; - - - public ClassFile(File classFile) throws IOException { - DataInputStream in = new DataInputStream(new BufferedInputStream( - new FileInputStream(classFile))); - try { - init(in); - } finally { - in.close(); - } - } - - - public ClassFile(DataInputStream in) throws IOException { - init(in); - } - - - private void debugPrint(String text) { - if (DEBUG) { - System.out.println(text); - } - } - - - /** - * Returns the access flags for this class or interface. - * - * @return The access flags, as a bit field. - * @see AccessFlags - */ - public int getAccessFlags() { - return accessFlags; - } - - - /** - * Returns the specified attribute of this class file. - * - * @param index The index of the attribute. - * @return The attribute. - * @see #getAttributeCount() - */ - public AttributeInfo getAttribute(int index) { - return attributes[index]; - } - - - /** - * Returns the number of attributes of this class file. - * - * @return The number of attributes. - * @see #getAttribute(int) - */ - public int getAttributeCount() { - return attributes==null ? 0 : attributes.length; - } - - - /** - * Returns the name of this class or interface. - * - * @param fullyQualified Whether the name should be fully-qualified. - * @return The name of this class or interface. - * @see #getSuperClassName(boolean) - */ - public String getClassName(boolean fullyQualified) { - return getClassNameFromConstantPool(thisClass, fullyQualified); - } - - - /** - * Given an index into the constant pool of a {@link ConstantClassInfo}, - * this method returns the fully-qualified name of the class it points to. - * - * @param cpIndex The index into the constant pool. Note that - * this value is 1-based. - * @param fullyQualified Whether the returned class name should be fully - * qualified. - * @return The fully-qualified class or interface name. - */ - protected String getClassNameFromConstantPool(int cpIndex, - boolean fullyQualified) { - - ConstantPoolInfo cpi = getConstantPoolInfo(cpIndex); - - if (cpi instanceof ConstantClassInfo) { - ConstantClassInfo cci = (ConstantClassInfo)cpi; - int index = cci.getNameIndex(); - ConstantUtf8Info cui = (ConstantUtf8Info)getConstantPoolInfo(index); - String className = cui.getRepresentedString(false); - if (fullyQualified) { - className = className.replace('/', '.'); - } - else { - className = className.substring(className.lastIndexOf('/')+1); - } - return className.replace('$', '.'); - } - - // cpi is never null - throw new InternalError("Expected ConstantClassInfo, found " + - cpi.getClass().toString()); - - } - - - /** - * Returns the size of the constant pool, plus 1. - * - * @return The size of the constant pool, plus 1. - * @see #getConstantPoolInfo(int) - */ - public int getConstantPoolCount() { - return constantPool.length + 1; - } - - - /** - * Returns the constant pool entry at the specified index. Note that - * constant pool entries are 1-based (that is, valid indices - * are 1 - getConstantPoolCount()-1). - * - * @param index The index into the constant pool to retrieve. - * @return The constant pool entry, or null if - * index is 0 (e.g. this - * ClassFile object represents - * java.lang.Object). - * @see #getConstantPoolCount() - */ - public ConstantPoolInfo getConstantPoolInfo(int index) { - return index!=0 ? constantPool[index-1] : null; - } - - - /** - * Returns the number of fields declared in this class file. - * - * @return The number of fields. - * @see #getFieldInfo(int) - */ - public int getFieldCount() { - return fields==null ? 0 : fields.length; - } - - - /** - * Returns the specified field's information. - * - * @param index The index of the field info. - * @return The field's information. - * @see #getFieldCount() - * @see #getFieldInfoByName(String) - */ - public FieldInfo getFieldInfo(int index) { - return fields[index]; - } - - - /** - * Returns a field's information by name. - * - * @param name The name of the field. - * @return The field's information. - * @see #getFieldCount() - * @see #getFieldInfo(int) - */ - public FieldInfo getFieldInfoByName(String name) { - for (int i=0; inull - * if none. This is a list of {@link MethodInfo}s. - * @see #getMethodInfoByName(String, int) - */ - public List getMethodInfoByName(String name) { - return getMethodInfoByName(name, -1); - } - - - /** - * Returns all method overloads with the specified name and number of - * arguments. - * - * @param name The method name. - * @param argCount The number of arguments. If this is less than zero, - * all overloads will be returned, regardless of argument count. - * @return Any method overloads with the given name and argument count, or - * null if none. This is a list of - * {@link MethodInfo}s. - * @see #getMethodInfoByName(String) - */ - public List getMethodInfoByName(String name, int argCount) { - List methods = null; - for (int i=0; i(1); // Usually just 1 - } - methods.add(info); - } - } - } - return methods; - } - - - /** - * Returns the package for this class or interface. - * - * @return The package, or null if this class or interface - * is not in a package. - * @see #getClassName(boolean) - */ - public String getPackageName() { - String className = getClassName(true); - int dot = className.lastIndexOf('.'); - return dot==-1 ? null : className.substring(0, dot); - } - - - public List getParamTypes() { - return paramTypes; - } - - - /** - * Returns the fully-qualified name of the superclass of this class or - * interface. - * - * @param fullyQualified Whether the returned value should be fully - * qualified. - * @return The name of the superclass of this class or interface. If this - * is an interface, then "java.lang.Object" is - * returned. If this class file represents - * java.lang.Object, then null is - * returned. - * @see #getClassName(boolean) - */ - public String getSuperClassName(boolean fullyQualified) { - if (superClass==0) { // This is java.lang.Object - return null; - } - return getClassNameFromConstantPool(superClass, fullyQualified); - } - - - /** - * Returns the currently set type argument for the specified type parameter. - * - * @param typeParam The type parameter. - * @return The type argument, or "Object" if no type - * parameters have been set. This is because, if the user types, - * say, "java.util.List list;" in Java 5+, the - * type defaults to Object. The code completion API - * may set the type argument mapping to null if no - * type arguments are scanned, thus we need to return - * Object in this case. - * @see #setTypeParamsToTypeArgs(Map) - */ - public String getTypeArgument(String typeParam) { - // If no type arguments are specified for a class that's supposed to - // have them (according to calling code), return "Object", as Java - // assumes this. - return typeMap==null ? "Object" : (String)typeMap.get(typeParam); - } - - - /** - * Returns the string value represented by a ConstantUtf8Info - * entry in the constant pool. - * - * @param index The index into the constant pool of a - * ConstantUtf8Info structure. This should be - * 1-based. - * @return The string represented. - */ - public String getUtf8ValueFromConstantPool(int index) { - ConstantPoolInfo cpi = getConstantPoolInfo(index); - ConstantUtf8Info cui = (ConstantUtf8Info)cpi; - return cui.getRepresentedString(false); - } - - - /** - * Returns the version number of this class, as a string. - * - * @return The class's version number, in the form - * major.minor. - */ - public String getVersionString() { - return majorVersion + "." + minorVersion; - } - - - /** - * Parses the class file from a given input stream. - * - * @param in - * @throws IOException If an error occurs reading the class file. - */ - private void init(DataInputStream in) throws IOException { - readHeader(in); - readVersion(in); - readConstantPoolInfos(in); - readAccessFlags(in); - readThisClass(in); - readSuperClass(in); - readInterfaces(in); - readFields(in); - readMethods(in); - readAttributes(in); - } - - - /** - * Returns whether this class is deprecated. - * - * @return Whether this class is deprecated. - */ - public boolean isDeprecated() { - return deprecated; - } - - - /** - * Reads this class or interface's access flags. - * - * @param in - * @throws IOException If an error occurs reading the access flags. - */ - private void readAccessFlags(DataInputStream in) throws IOException { - accessFlags = in.readUnsignedShort(); - debugPrint("Access flags: " + accessFlags); - } - - - /** - * Reads a single attribute of this class file. - * - * @param in The input stream to read from. - * @return The attribute. - * @throws IOException If an IO error occurs. - */ - private AttributeInfo readAttribute(DataInputStream in) throws IOException { - - AttributeInfo ai = null; - - int attributeNameIndex = in.readUnsignedShort(); - int attributeLength = in.readInt(); - - String attrName = getUtf8ValueFromConstantPool(attributeNameIndex); - debugPrint("Found class attribute: " + attrName); - - if (SOURCE_FILE.equals(attrName)) { // 4.7.7 - int sourceFileIndex = in.readUnsignedShort(); - SourceFile sf = new SourceFile(this, sourceFileIndex); - ai = sf; - } - - else if (BOOTSTRAP_METHODS.equals(attrName)) { // 4.7.23 - //String name = getClassFile().getClassName(false) + "." + getName(); - //System.out.println(name + ": Attribute " + attrName + " not supported"); - Util.skipBytes(in, attributeLength); - //ai = null; - } - - else if (SIGNATURE.equals(attrName)) { // 4.8.8 - int signatureIndex = in.readUnsignedShort(); - String sig = getUtf8ValueFromConstantPool(signatureIndex); - //System.out.println("... Signature: " + sig); - ai = new Signature(this, sig); - paramTypes = ((Signature)ai).getClassParamTypes(); - } - - else if (INNER_CLASSES.equals(attrName)) { // 4.8.5 - //String name = getClassName(false) + "." + getName(); - //System.out.println(name + ": Attribute " + attrName + " not supported"); - Util.skipBytes(in, attributeLength); - //ai = null; - } - - else if (ENCLOSING_METHOD.equals(attrName)) { // 4.8.6 - //String name = getClassName(false) + "." + getName(); - //System.out.println(name + ": Attribute " + attrName + " not supported"); - Util.skipBytes(in, attributeLength); // 2 u2's, class_index and method_index - //ai = null; - } - - else if (DEPRECATED.equals(attrName)) { // 4.7.10 - // No need to read anything else, attributeLength==0 - deprecated = true; - } - - else if (RUNTIME_VISIBLE_ANNOTATIONS.equals(attrName)) { // 4.8.15 - //String name = getClassFile().getClassName(false) + "." + getName(); - //System.out.println(name + ": Attribute " + attrName + " not supported"); - Util.skipBytes(in, attributeLength); - //ai = null; - } - - // TODO: Handle other useful Attribute types, if any. - - else { // An unknown/unsupported attribute. - System.out.println("Unsupported class attribute: "+ attrName); - ai = AttributeInfo.readUnsupportedAttribute(this, in, attrName, - attributeLength); - } - - return ai; - - } - - - /** - * Reads this class file's attributes. - * - * @param in The input stream to read from. - * @throws IOException If an IO error occurs. - */ - private void readAttributes(DataInputStream in) throws IOException { - int attributeCount = in.readUnsignedShort(); - if (attributeCount>0) { - attributes = new AttributeInfo[attributeCount]; - for (int i=0; i0) { - fields = new FieldInfo[fieldCount]; - for (int i=0; i0xCAFEBABE class file header. - * - * @param in - * @throws IOException If the header is invalid. - */ - private void readHeader(DataInputStream in) throws IOException { - for (int i=0; i0) { - interfaces = new int[interfaceCount]; - for (int i=0; i0) { - methods = new MethodInfo[methodCount]; - for (int i=0; iClassFile - * does not directly use this field; it is there for code completion API's - * to use to extract the necessary types of arguments, return values, etc., - * of methods (see the {@link MethodInfo} class). - * - * @param typeMap A mapping of type parameters to type arguments (both - * Strings). - * @see #getTypeArgument(String) - */ - public void setTypeParamsToTypeArgs(Map typeMap) { - this.typeMap = typeMap; - for (int i=0; icatch or finally block (the section of code it - * covers, the type of Throwable it handles, and the location of the - * exception handler code). - * - * @author Robert Futrell - * @version 1.0 - */ -public class ExceptionTableEntry { - - /** - * The parent class file. - */ - private ClassFile cf; - - /** - * Start of the range in the code array at which the exception handler is - * active. - */ - private int startPC; // u2 - - /** - * End of the range in the code array at which the exception handler is - * active. This value must be either a valid index into the code array of - * the opcode of an instruction, or be equal to - * {@link Code#getCodeLength()}. - */ - private int endPC; // u2 - - /** - * The start of the exception handler. This value must be a valid index - * into the code array and must be the index of the opcode of an - * instruction. - */ - private int handlerPC; // u2 - - /** - * If the value of {@link #catchType} is nonzero, it must be a valid - * index into the constant pool. The constant pool entry at that index - * must be a {@link ConstantClassInfo} structure representing a class of - * exceptions that this exception handler is designated to catch. This - * class must be the class Throwable or one of its subclasses. - * The exception handler will be called only if the thrown exception is - * an instance of the given class or one of its subclasses.

    - * - * If the value of {@link #catchType} is zero, this exception handler is - * for all exceptions. This is used to implement finally. - */ - private int catchType; // u2 - - - /** - * Constructor. - * - * @param cf The parent class file. - */ - public ExceptionTableEntry(ClassFile cf) { - this.cf = cf; - } - - - /** - * Returns the name of the Throwable type caught and handled - * by this exception handler. - * - * @param fullyQualified Whether the name should be fully qualified. - * @return The name of the Throwable type, or null - * if this entry denotes a finally block. - */ - public String getCaughtThrowableType(boolean fullyQualified) { - return catchType==0 ? null : - cf.getClassNameFromConstantPool(catchType, fullyQualified); - } - - - public int getEndPC() { - return endPC; - } - - - public int getHandlerPC() { - return handlerPC; - } - - - public int getStartPC() { - return startPC; - } - - - /** - * Reads an exception table entry from an input stream. - * - * @param cf The class file. - * @param in The input stream to read from. - * @return The exception table entry. - * @throws IOException If an IO error occurs. - */ - public static ExceptionTableEntry read(ClassFile cf, DataInputStream in) - throws IOException { - ExceptionTableEntry entry = new ExceptionTableEntry(cf); - entry.startPC = in.readUnsignedShort(); - entry.endPC = in.readUnsignedShort(); - entry.handlerPC = in.readUnsignedShort(); - entry.catchType = in.readUnsignedShort(); - return entry; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/FieldInfo.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/FieldInfo.java deleted file mode 100644 index 73cd531e..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/classreader/FieldInfo.java +++ /dev/null @@ -1,279 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.classreader; - -import org.fife.rsta.ac.bsh.classreader.attributes.ConstantValue; -import org.fife.rsta.ac.bsh.classreader.attributes.AttributeInfo; -import java.io.*; -import java.util.*; - - - -/** - * Represents a "field_info" structure as defined by the Java VM spec. - * - * @author Robert Futrell - * @version 1.0 - */ -public class FieldInfo extends MemberInfo { - - /** - * Index into the constant pool of a {@link ConstantUtf8Info} structure - * representing the field name, as a simple name. - */ - private int nameIndex; // u2 - - /** - * Index into the constant pool of a {@link ConstantUtf8Info} structure - * representing a valid field descriptor. - */ - private int descriptorIndex; // u2 - - /** - * An array of attributes of this field. - */ - private List attributes; - - public static final String CONSTANT_VALUE = "ConstantValue"; - - - /** - * Constructor. - * - * @see AccessFlags - */ - public FieldInfo(ClassFile cf, int accessFlags, int nameIndex, - int descriptorIndex) { - super(cf, accessFlags); - this.nameIndex = nameIndex; - this.descriptorIndex = descriptorIndex; - attributes = new ArrayList(1); // Usually 0 or 1? - } - - - /** - * Adds the specified attribute to this field. - * - * @param info Information about the attribute. - */ - public void addAttribute(AttributeInfo info) { - attributes.add(info); - } - - - /** - * Returns the specified attribute. - * - * @param index The index of the attribute. - * @return The attribute. - */ - public AttributeInfo getAttribute(int index) { - return attributes.get(index); - } - - - /** - * Returns the number of attributes of this field. - * - * @return The number of attributes. - */ - public int getAttributeCount() { - return attributes.size(); - } - - - public String getConstantValueAsString() { - ConstantValue cv = getConstantValueAttributeInfo(); - return cv==null ? null : cv.getConstantValueAsString(); - } - - - /** - * Returns the {@link ConstantValue} attribute info for this field, if any. - * - * @return The ConstantValue attribute, or null - * if there isn't one. - */ - private ConstantValue getConstantValueAttributeInfo() { - for (int i=0; iFieldInfo structure from the specified input - * stream. - * - * @param cf The class file containing this field. - * @param in The input stream to read from. - * @return The field information read. - * @throws IOException If an IO error occurs. - */ - public static FieldInfo read(ClassFile cf, DataInputStream in) - throws IOException { - FieldInfo info = new FieldInfo(cf, in.readUnsignedShort(), - in.readUnsignedShort(), - in.readUnsignedShort()); - int attrCount = in.readUnsignedShort(); - for (int i=0; inull if it was known - * to be unimportant for our purposes. - * @throws IOException If an IO error occurs. - */ - private AttributeInfo readAttribute(DataInputStream in) throws IOException { - - AttributeInfo ai = null; - - int attributeNameIndex = in.readUnsignedShort(); - int attributeLength = in.readInt(); - - String attrName = cf.getUtf8ValueFromConstantPool(attributeNameIndex); - - if (CONSTANT_VALUE.equals(attrName)) { // 4.7.2 - int constantValueIndex = in.readUnsignedShort(); - ConstantValue cv = new ConstantValue(cf, constantValueIndex); - ai = cv; - } - - // Attributes common to all members, or unhandled attributes. - else { - ai = super.readAttribute(in, attrName, attributeLength); - } - - return ai; - - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/Frame.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/Frame.java deleted file mode 100644 index 09ae3491..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/classreader/Frame.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.classreader; - -import java.util.*; - -import org.fife.rsta.ac.bsh.classreader.attributes.Code; - - -/** - * A Frame contains information on a method being decompiled, - * similar to a Frame as defined in 3.6 of the JVM spec. - * - * @author Robert Futrell - * @version 1.0 - */ -public class Frame { - - private Stack operandStack; - private LocalVarInfo[] localVars; - - - /** - * Constructor. - * - * @param code The {@link Code} attribute being decompiled. - */ - public Frame(Code code) { - - operandStack = new Stack(); - - localVars = new LocalVarInfo[code.getMaxLocals()]; - int i = 0; - MethodInfo mi = code.getMethodInfo(); - - // Instance methods have an implicit first parameter of "this". - if (!mi.isStatic()) { - localVars[i++] = new LocalVarInfo("this", true); - } - - // Name the passed-in local vars by their types. longs and doubles - // take up two slots. - String[] paramTypes = mi.getParameterTypes(); - for (int param_i=0; param_i-1) { // Class types. - type = type.substring(type.lastIndexOf('.')+1); - } - String name = "localVar_" + type + "_" + param_i; - localVars[i] = new LocalVarInfo(name, true); - i++; - if ("long".equals(type) || "double".equals(type)) { - i++; // longs and doubles take up two slots. - } - } - - // NOTE: Other local vars will still be "null" here! We need to - // infer their types from their usage during disassembly/decompilation. - System.out.println("NOTE: " + (localVars.length-i) + " unknown localVars slots"); - - } - - - public LocalVarInfo getLocalVar(int index, String defaultType) { - LocalVarInfo var = localVars[index]; - if (var==null) { - String name = "localVar_" + defaultType + "_" + index; - var = new LocalVarInfo(name, false); - localVars[index] = var; - } - else { - var.alreadyDeclared = true; // May be redundant - } - return var; - } - - - public String pop() { - return operandStack.pop(); - } - - - public void push(String value) { - operandStack.push(value); - } - - - public static class LocalVarInfo { - - private String value; - private boolean alreadyDeclared; - - public LocalVarInfo(String value, boolean alreadyDeclared) { - this.value = value; - this.alreadyDeclared = alreadyDeclared; - } - - public String getValue() { - return value; - } - - public boolean isAlreadyDeclared() { - return alreadyDeclared; - } - - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/MemberInfo.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/MemberInfo.java deleted file mode 100644 index 14896f81..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/classreader/MemberInfo.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.classreader; - -import java.io.DataInputStream; -import java.io.IOException; - -import org.fife.rsta.ac.bsh.classreader.attributes.AttributeInfo; -import org.fife.rsta.ac.bsh.classreader.attributes.Signature; - - -/** - * Base class for information about members (fields and methods). - * - * @author Robert Futrell - * @version 1.0 - * @see FieldInfo - * @see MethodInfo - */ -public abstract class MemberInfo { - - /** - * The class file in which this method is defined. - */ - protected ClassFile cf; - - /** - * A mask of flags used to denote access permission to and properties of - * this method. - */ - private int accessFlags; // u2 - - /** - * Whether this member is deprecated. - */ - private boolean deprecated; - - /** - * Attribute marking a member as deprecated. - */ - public static final String DEPRECATED = "Deprecated"; - - /** - * Attribute containing index of the member's signature. - */ - public static final String SIGNATURE = "Signature"; - - /** - * Attribute containing runtime-visible annotations. - */ - public static final String RUNTIME_VISIBLE_ANNOTATIONS = "RuntimeVisibleAnnotations"; - - - /** - * Constructor. - * - * @param cf The class file defining this member. - */ - protected MemberInfo(ClassFile cf, int accessFlags) { - this.cf = cf; - this.accessFlags = accessFlags; - } - - - /** - * Returns the access flags for this field. - * - * @return The access flags, as a bit field. - * @see AccessFlags - */ - public int getAccessFlags() { - return accessFlags; - } - - - /** - * Returns the parent class file. - * - * @return The parent class file. - */ - public ClassFile getClassFile() { - return cf; - } - - - /** - * Returns the name of this member. - * - * @return The name of this member. - */ - public abstract String getName(); - - - /** - * Returns whether this member is deprecated. - * - * @return Whether this member is deprecated. - */ - public boolean isDeprecated() { - return deprecated; - } - - - /** - * Returns the descriptor of this member. - * - * @return The descriptor of this member. - */ - public abstract String getDescriptor(); - - - /** - * Returns whether this member is final. - * - * @return Whether this member is final. - */ - public boolean isFinal() { - return (getAccessFlags()&AccessFlags.ACC_FINAL)>0; - } - - - /** - * Returns whether this member is static. - * - * @return Whether this member is static. - */ - public boolean isStatic() { - return (getAccessFlags()&AccessFlags.ACC_STATIC)>0; - } - - - /** - * Reads attributes common to all members. If the specified attribute is - * not common to members, the attribute returned is an "unsupported" - * attribute. - * - * @param in - * @param attrName - * @param attrLength - * @return The attribute, or null if it was purposely skipped - * for some reason (known to be useless for our purposes, etc.). - * @throws IOException - */ - protected AttributeInfo readAttribute(DataInputStream in, String attrName, - int attrLength) throws IOException { - - AttributeInfo ai = null; - - if (DEPRECATED.equals(attrName)) { // 4.7.10 - // No need to read anything else, attributeLength==0 - deprecated = true; - } - - else if (SIGNATURE.equals(attrName)) { // 4.8.8 - //System.err.println(">>> " + attributeLength); - int signatureIndex = in.readUnsignedShort(); - String typeSig = cf.getUtf8ValueFromConstantPool(signatureIndex); - ai = new Signature(cf, typeSig); - } - - else if (RUNTIME_VISIBLE_ANNOTATIONS.equals(attrName)) { // 4.8.15 - //String name = getClassFile().getClassName(false) + "." + getName(); - //System.out.println(name + ": Attribute " + attrName + " not supported"); - Util.skipBytes(in, attrLength); - //ai = null; - } - - else { - //String name = getClassFile().getClassName(false) + "." + getName(); - //System.out.println(name + ": Unsupported attribute: " + attrName); - ai = AttributeInfo.readUnsupportedAttribute(cf, in, attrName, - attrLength); - } - - return ai; - - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/MethodInfo.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/MethodInfo.java deleted file mode 100644 index 9bebc73b..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/classreader/MethodInfo.java +++ /dev/null @@ -1,721 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.classreader; - -import org.fife.rsta.ac.bsh.classreader.attributes.Exceptions; -import org.fife.rsta.ac.bsh.classreader.attributes.Signature; -import org.fife.rsta.ac.bsh.classreader.attributes.Code; -import org.fife.rsta.ac.bsh.classreader.attributes.AttributeInfo; -import java.io.*; -import java.util.*; - - - -/** - * Implementation of the "method_info" structure as defined in - * the JVM specification. - * - * @author Robert Futrell - * @version 1.0 - */ -public class MethodInfo extends MemberInfo implements AccessFlags { - - /** - * An index into the constant pool of a {@link ConstantUtf8Info} structure - * representing either one of the special method names ( - * "<init>" or "<clinit>") or a - * valid method name in the Java programming language, stored as a simple - * name. - */ - private int nameIndex; // u2 - - /** - * An index into the constant pool of a {@link ConstantUtf8Info} structure - * representing a valid method descriptor. - */ - private int descriptorIndex; // u2 - - /** - * The Signature attribute, or null if there - * isn't one for this method. - */ - private Signature signatureAttr; - - /** - * The Code attribute, or null if this method - * is abstract or native. - */ - private Code codeAttr; - - /** - * All attributes of this method that aren't explicitly covered by the - * private members {@link #signatureAttr} and {@link #codeAttr}. - */ - private List attributes; - - /** - * The type of all parameters to this method. Note that this cache will - * be short-lived, as classes that take type parameters will pass their - * type arguments down to individual MethodInfos when doing - * completions, to ensure types are as correct as possible. - */ - private String[] paramTypes; - - /** - * Cached return type. - */ - private String returnType; - - /** - * Cached string representing the name and parameters for this method. - */ - private String nameAndParameters; - - /** - * Used in class files to denote constructors. - */ - private static final String SPECIAL_NAME_CONSTRUCTOR = ""; - - public static final String CODE = "Code"; - public static final String EXCEPTIONS = "Exceptions"; - - - /** - * Constructor. - * - * @param cf The class file defining this method. - */ - public MethodInfo(ClassFile cf, int accessFlags, int nameIndex, - int descriptorIndex) { - super(cf, accessFlags); - this.nameIndex = nameIndex; - this.descriptorIndex = descriptorIndex; - attributes = new ArrayList(1); // Usually only 0 or 1? - } - - - /** - * Adds the specified attribute to this field. - * - * @param info Information about the attribute. - */ - private void addAttribute(AttributeInfo info) { - attributes.add(info); - } - - - private void appendParamDescriptors(StringBuilder sb) { - - String[] paramTypes = getParameterTypes(); - for (int i=0; iMethodInfo to be used for code completion for instances - * of the same class initialized with different type arguments.

    - * - * Note that if this method does not have parameterized arguments or - * return type, calling this method won't affect its behavior. - */ - void clearParamTypeInfo() { - paramTypes = null; - returnType = null; - } - - - /** - * Creates and returns an array of types of all parameters of this - * method. If this method takes any generic type arguments, these - * types are grabbed from the parent ClassFile instance, - * whose type argument values should have been initialized via - * {@link ClassFile#setTypeParamsToTypeArgs(Map)}. - * - * @return The array of parameter types. - * @see #createParamTypesFromDescriptor() - * @see #createParamTypesFromTypeSignature() - */ - private String[] createParamTypes() { - String[] types = createParamTypesFromTypeSignature(); - if (types==null) { - types = createParamTypesFromDescriptor(true); - } - return types; - } - - - /** - * Creates an array of types of each parameter by looking at the method's - * descriptor field. This technique should work with Java 1.0+, but won't - * pick up on generic types added in Java 5. - * - * @return The parameter types. - * @see #createParamTypesFromTypeSignature() - */ - private String[] createParamTypesFromDescriptor(boolean qualified) { - - String descriptor = getDescriptor(); - int rparen = descriptor.indexOf(')'); - String paramDescriptors = descriptor.substring(1, rparen); - //String returnDescriptor = descriptor.substring(rparen+1); - - List paramTypeList = new ArrayList(); - String type = null; - - while (paramDescriptors.length()>0) { - - // Can't do lastIndexOf() as there may be > 1 array parameter - // in the descriptors. - // int braceCount = paramDescriptors.lastIndexOf('[') + 1; - int braceCount = -1; - while (paramDescriptors.charAt(++braceCount) == '['); - int pos = braceCount; - - switch (paramDescriptors.charAt(pos)) { - - // BaseType - case 'B': - type = "byte"; - pos++; - break; - case 'C': - type = "char"; - pos++; - break; - case 'D': - type = "double"; - pos++; - break; - case 'F': - type = "float"; - pos++; - break; - case 'I': - type = "int"; - pos++; - break; - case 'J': - type = "long"; - pos++; - break; - case 'S': - type = "short"; - pos++; - break; - case 'Z': - type = "boolean"; - pos++; - break; - - // ObjectType - case 'L': - String clazz = paramDescriptors.substring(pos + 1, - paramDescriptors.indexOf(';')); - type = qualified ? clazz.replace('/', '.') : clazz.substring(clazz.lastIndexOf('/')+1); - pos += clazz.length() + 2; // "+2" for the 'L' & semicolon - break; - - // Invalid method descriptor - default: - String temp = "INVALID_TYPE_" + paramDescriptors; - type = temp; - pos += paramDescriptors.length(); - break; - - } - - for (int i = 0; i < braceCount; i++) { - type += "[]"; - } - paramTypeList.add(type); - - paramDescriptors = paramDescriptors.substring(pos); - - } - - String[] types = new String[paramTypeList.size()]; - types = paramTypeList.toArray(types); - return types; - - } - - - /** - * Creates an array of types of each parameter by looking at the method's - * Signature attribute, and querying the parent - * ClassFile instance for any type argument values. This - * attribute was introduced in Java 5, and is the only way to detect - * generic parameters. - * - * @return The parameter types. - * @see #createParamTypesFromDescriptor() - */ - private String[] createParamTypesFromTypeSignature() { - - String[] params = null; - - if (signatureAttr!=null) { - List paramTypes = signatureAttr. - getMethodParamTypes(this, cf, false); - if (paramTypes!=null) { - params = new String[paramTypes.size()]; - params = paramTypes.toArray(params); - } - } - - return params; - - } - - - /** - * Returns the specified attribute. - * - * @param index The index of the attribute. - * @return The attribute. - */ - public AttributeInfo getAttribute(int index) { - return attributes.get(index); - } - - - /** - * Returns the number of attributes of this field. - * - * @return The number of attributes. - */ - public int getAttributeCount() { - return attributes.size(); - } - - - /** - * {@inheritDoc} - */ - @Override - public String getDescriptor() { - return cf.getUtf8ValueFromConstantPool(descriptorIndex); - } - - - /** - * {@inheritDoc} - */ - @Override - public String getName() { - String name = cf.getUtf8ValueFromConstantPool(nameIndex); - if (SPECIAL_NAME_CONSTRUCTOR.equals(name)) { - name = cf.getClassName(false); - } - return name; - } - - - /** - * Returns the name and parameters of this method, in the form - * performAction(String, int, Runnable). - * - * @return The name and parameters of this method. - */ - public String getNameAndParameters() { - - if (nameAndParameters==null) { - - StringBuilder sb = new StringBuilder(getName()); - - sb.append('('); - int paramCount = getParameterCount(); - for (int i=0; inull - * is returned. - * - * @param index The index of the parameter. - * @return The name of the parameter, or null. - */ - public String getParameterName(int index) { - if (index>=0 && index-1) { - type = type.substring(dot+1); - } - } - return type; - } - - - /** - * Returns an array if strings representing the types of all parameters - * to this method. If this method takes no parameters, a zero-length - * array is returned. - * - * @return The array. These types will likely be fully qualified. - * @see #getParameterCount() - * @see #getParameterType(int, boolean) - */ - public String[] getParameterTypes() { - if (paramTypes==null) { - paramTypes = createParamTypes(); - } - return paramTypes.clone(); - } - - /** - * Returns the return type of this method. - * - * @return The return type of this method. - */ - public String getReturnTypeString(boolean fullyQualified) { - if (returnType==null) { - returnType = getReturnTypeStringFromTypeSignature(fullyQualified); - if (returnType==null) { - returnType = getReturnTypeStringFromDescriptor(fullyQualified); - } - } - if(!fullyQualified) - { - if(returnType != null && returnType.indexOf(".") > -1) { - return returnType.substring(returnType.lastIndexOf(".") +1, returnType.length()); - } - } - return returnType; - } - - - /** - * Returns the return type of this method, as determined by a snippet - * of the method descriptor. This should work with all class files - * created in Java 1.0+, but won't discover the generic types added in - * Java 5. - * - * @return The return type of this method. - * @see #getReturnTypeStringFromTypeSignature() - */ - /* - * TODO: This is identical to FieldInfo.getTypeString(), except for the - * 'V' case. It is also very similar to #getParameterTypes(). Try - * to refactor common code from these methods. - */ - private String getReturnTypeStringFromDescriptor(boolean qualified) { - - String descriptor = getDescriptor(); - int rparen = descriptor.indexOf(')'); - descriptor = descriptor.substring(rparen+1); // return type desc. - StringBuilder sb = new StringBuilder(); - - int braceCount = descriptor.lastIndexOf('[') + 1; - - switch (descriptor.charAt(braceCount)) { - - // BaseType - case 'B': - sb.append("byte"); - break; - case 'C': - sb.append("char"); - break; - case 'D': - sb.append("double"); - break; - case 'F': - sb.append("float"); - break; - case 'I': - sb.append("int"); - break; - case 'J': - sb.append("long"); - break; - case 'S': - sb.append("short"); - break; - case 'Z': - sb.append("boolean"); - break; - case 'V': - sb.append("void"); - break; - - // ObjectType - case 'L': - String clazz = descriptor.substring(braceCount+1, descriptor.length()-1); - clazz = qualified ? clazz.replace('/', '.') : clazz.substring(clazz.lastIndexOf('/')+1); - sb.append(clazz); - break; - - // Invalid field descriptor - default: - sb.append("UNSUPPORTED_TYPE_").append(descriptor); - break; - - } - - for (int i=0; iSignature attribute that was added in Java 5. This allows - * us to check for generic types. - * - * @return The return type of this method. - * @see #getReturnTypeStringFromDescriptor() - */ - private String getReturnTypeStringFromTypeSignature(boolean qualified) { - String retType = null; - if (signatureAttr!=null) { - retType = signatureAttr.getMethodReturnType(this, cf, qualified); - } - - return retType; - - } - - - /** - * Returns the signature of this method, as determined from its method - * descriptor. - * - * @return The signature of this method. - */ - public String getSignature() { - - StringBuilder sb = new StringBuilder(); - - // Return type. - if (!isConstructor()) { // Don't print "void" return type. - sb.append(getReturnTypeString(false)); - sb.append(' '); - } - - // Method name and param list. - sb.append(getName()); - sb.append('('); - appendParamDescriptors(sb); - sb.append(')'); - - // "throws" clause. - for (AttributeInfo ai : attributes) { - if (ai instanceof Exceptions) { // At most 1 Exceptions attribute - sb.append(" throws "); - Exceptions ex = (Exceptions)ai; - for (int j=0; j0; - } - - - /** - * Returns whether this method is a constructor. - * - * @return Whether this method is a constructor. - */ - public boolean isConstructor() { - String name = cf.getUtf8ValueFromConstantPool(nameIndex); - return SPECIAL_NAME_CONSTRUCTOR.equals(name); - } - - - /** - * Returns whether this method is native. - * - * @return Whether this method is native. - */ - public boolean isNative() { - return (getAccessFlags()&ACC_NATIVE)>0; - } - - - /** - * Returns whether this method is static. - * - * @return Whether this method is static. - */ - @Override - public boolean isStatic() { - return (getAccessFlags()&ACC_STATIC)>0; - } - - - /** - * Reads a MethodInfo from an input stream. - * - * @param cf The class file defining the method. - * @param in The input stream to read from. - * @return The method information read. - * @throws IOException If an IO error occurs. - */ - public static MethodInfo read(ClassFile cf, DataInputStream in) - throws IOException { - int accessFlags = in.readUnsignedShort(); - int nameIndex = in.readUnsignedShort(); - int descriptorIndex = in.readUnsignedShort(); - MethodInfo mi = new MethodInfo(cf, accessFlags, nameIndex, - descriptorIndex); - int attrCount = in.readUnsignedShort(); - for (int j=0; jnull if it was known - * to be unimportant for our purposes. - * @throws IOException If an IO error occurs. - */ - private AttributeInfo readAttribute(DataInputStream in) throws IOException { - - AttributeInfo ai = null; - - int attributeNameIndex = in.readUnsignedShort(); - int attributeLength = in.readInt(); - - String attrName = cf.getUtf8ValueFromConstantPool(attributeNameIndex); - - if (CODE.equals(attrName)) { // 4.7.3 - ai = Code.read(this, in); - } - - else if (EXCEPTIONS.equals(attrName)) { // 4.7.4 - int exceptionCount = in.readUnsignedShort(); - int[] exceptionIndexTable = null; - if (exceptionCount>0) { - exceptionIndexTable = new int[exceptionCount]; - for (int i=0; i0; - } - - - /** - * Returns whether an object has protected scope. - * - * @return Whether an object has protected scope. - * @see #isDefault(int) - * @see #isPrivate(int) - * @see #isPublic(int) - */ - public static boolean isProtected(int accessFlags) { - return (accessFlags&ACC_PROTECTED)>0; - } - - - /** - * Returns whether an object has public scope. - * - * @return Whether an object has public scope. - * @see #isDefault(int) - * @see #isPrivate(int) - * @see #isPublic(int) - */ - public static boolean isPublic(int accessFlags) { - return (accessFlags&ACC_PUBLIC)>0; - } - - - /** - * Fully skips a given number of bytes in an input stream. - * - * @param in The input stream. - * @param count The number of bytes to skip. - * @throws IOException If an IO error occurs. - */ - public static void skipBytes(DataInputStream in, int count) - throws IOException { - int skipped = 0; - while (skippedin, - * in bytes. - * @return The attribute. - * @throws IOException If an IO error occurs. - */ - public static UnsupportedAttribute readUnsupportedAttribute(ClassFile cf, - DataInputStream in, String attrName, - int attrLength) throws IOException { - /* - int[] info = new int[attrLength]; - for (int i=0; iCode attribute contains the - * JVM instructions and auxiliary information for a single method, instance - * initialization method, or class or interface initialization method. Every - * JVM implementation must recognize Code attributes. If the - * method is either native or abstract, its - * MethodInfo structure must not have a Code - * attribute. Otherwise, its MethodInfo structure must have - * exactly one Code attribute. - * - * @author Robert Futrell - * @version 1.0 - */ -public class Code extends AttributeInfo { - - /** - * The parent method. - */ - private MethodInfo mi; - - /** - * The maximum depth of the operand stack of this method at any point - * during its execution. - */ - private int maxStack; - - /** - * The number of local variables in the local variable array allocated - * upon invocation of this method, including the local variables used to - * pass parameters to the method on invocation.

    - * - * The greatest local variable index for a value of type long - * or double is maxLocals-2. The greatest local - * variable index for a value of any other type is maxLocals-1. - */ - private int maxLocals; - -// /** -// * The actual bytes of JVM code that implement the method. This must have -// * length greater than zero. -// */ -// private int[] code; - - /** - * The size of the method's code, in bytes. - */ - private int codeLength; - - /** - * The exception handlers in the code array. The order of - * the handlers in this table is significant. - */ - private ExceptionTableEntry[] exceptionTable; - - /** - * The names of parameters to the parent method, if debugging was enabled - * during compilation. - * @see #LOCAL_VARIABLE_TABLE - */ - private String[] paramNames; - - /** - * Attributes of this Code attribute. - */ - private List attributes; - - private static final String LINE_NUMBER_TABLE = "LineNumberTable"; - private static final String LOCAL_VARIABLE_TABLE = "LocalVariableTable"; - private static final String LOCAL_VARIABLE_TYPE_TABLE = "LocalVariableTypeTable"; - private static final String STACK_MAP_TABLE = "StackMapTable"; - - - /** - * Constructor. - * - * @param mi Information on the parent method. - */ - public Code(MethodInfo mi) { - super(mi.getClassFile()); - this.mi = mi; - } - - -// /** -// * Returns the code byte at the specified offset. -// * -// * @param offset The offset. -// * @return The byte. -// */ -// public int getByte(int offset) { -// return code[offset]; -// } - - - /** - * Returns the length of the code array, in bytes. - * - * @return The length of the code array. - */ - public int getCodeLength() { - return codeLength;//code.length; - } - - - /** - * Returns the number of local variables in the local variable array - * allocated upon invocation of this method, including the local variables - * used to pass parameters to the method on invocation.

    - * - * The greatest local variable index for a value of type long - * or double is maxLocals-2. The greatest local - * variable index for a value of any other type is maxLocals-1. - * - * @return the maximum size of the local variable array. - */ - public int getMaxLocals() { - return maxLocals; - } - - - /** - * Returns the maximum depth of the operand stack of this method at any - * point during its execution. - */ - public int getMaxStack() { - return maxStack; - } - - - /** - * Returns the method containing this code. - * - * @return The method containing this code. - */ - public MethodInfo getMethodInfo() { - return mi; - } - - - /** - * If debugging was enabled during compilation, this method returns the - * name of the given parameter to this method. Otherwise, null - * is returned. - * - * @param index The index of the parameter. - * @return The name of the parameter, or null. - */ - public String getParameterName(int index) { - return paramNames==null ? null : paramNames[index]; - } - - - /** - * Reads a Code attribute from an input stream. - * - * @param mi The parent method. - * @param in The input stream. - * @return The Code attribute. - * @throws IOException If an IO error occurs. - */ - public static Code read(MethodInfo mi, DataInputStream in) - throws IOException { - - Code code = new Code(mi); - code.maxStack = in.readUnsignedShort(); - code.maxLocals = in.readUnsignedShort(); - code.codeLength = in.readInt(); - Util.skipBytes(in, code.codeLength); - - int exceptionTableLength = in.readUnsignedShort(); - if (exceptionTableLength>0) { - code.exceptionTable = new ExceptionTableEntry[exceptionTableLength]; - for (int i=0; i0) { - code.attributes = new ArrayList(1); // Usually 1 or 2 - for (int i=0; iCode attribute from an input - * stream. - * - * @param in The input stream to read from. - * @return The attribute read. - * @throws IOException If an IO error occurs. - */ - private AttributeInfo readAttribute(DataInputStream in) throws IOException { - - AttributeInfo ai = null; - ClassFile cf = mi.getClassFile(); - - int attributeNameIndex = in.readUnsignedShort(); - int attributeLength = in.readInt(); - - String attrName = cf.getUtf8ValueFromConstantPool(attributeNameIndex); - - // The line number table is more useful to a debugger than to us. - if (LINE_NUMBER_TABLE.equals(attrName)) { // 4.7.12 - //String name = mi.getName(true) + "."; - //System.out.println(name + ": Attribute " + attrName + " currently ignored"); - Util.skipBytes(in, attributeLength); - //ai = null; - } - - // Describes a local variable during execution of this code. We only - // use it to grab the names of method parameters. - else if (LOCAL_VARIABLE_TABLE.equals(attrName)) { // 4.7.13 - - // If this attribute is defined, then this class was compiled with - // debugging enabled! We can grab the names of the method - // parameters, to make code completion a little nicer. Note that - // we only grab the names of parameters, not all local variables, - // for speed and space. - - int paramCount = mi.getParameterCount(); - paramNames = new String[paramCount]; - boolean isStatic = mi.isStatic(); - - int localVariableTableLength = in.readUnsignedShort(); - for (int i=0; i=0 && adjustedIndexConstantValue" attribute, as defined by 4.7.2 of the - * JVM specification. - * - * @author Robert Futrell - * @version 1.0 - */ -public class ConstantValue extends AttributeInfo { - - /** - * An index into the constant pool that gives the constant value - * represented by this attribute. - */ - private int constantValueIndex; // u2 - - - /** - * CConstructor. - * - * @param cf The class file. - * @param constantValueIndex The index into the constant pool that gives - * the constant value represented by this attribute. - */ - public ConstantValue(ClassFile cf, int constantValueIndex) { - super(cf); - this.constantValueIndex = constantValueIndex; - } - - - /** - * Returns the index into the constant pool that gives the constant value - * represented by this attribute. - * - * @return The index. - */ - public int getConstantValueIndex() { - return constantValueIndex; - } - - - /** - * Returns the constant's value, as a string. - * - * @return The constant's value, as a string. - */ - public String getConstantValueAsString() { - - ClassFile cf = getClassFile(); - ConstantPoolInfo cpi = cf.getConstantPoolInfo(getConstantValueIndex()); - - if (cpi instanceof ConstantDoubleInfo) { - ConstantDoubleInfo cdi = (ConstantDoubleInfo)cpi; - double value = cdi.getDoubleValue(); - return Double.toString(value); - } - else if (cpi instanceof ConstantFloatInfo) { - ConstantFloatInfo cfi = (ConstantFloatInfo)cpi; - float value = cfi.getFloatValue(); - return Float.toString(value); - } - else if (cpi instanceof ConstantIntegerInfo) { - ConstantIntegerInfo cii = (ConstantIntegerInfo)cpi; - int value = cii.getIntValue(); - return Integer.toString(value); - } - else if (cpi instanceof ConstantLongInfo) { - ConstantLongInfo cli = (ConstantLongInfo)cpi; - long value = cli.getLongValue(); - return Long.toString(value); - } - else if (cpi instanceof ConstantStringInfo) { - ConstantStringInfo csi = (ConstantStringInfo)cpi; - return csi.getStringValue(); - } - else { - return "INVALID_CONSTANT_TYPE_" + cpi.toString(); - } - - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/attributes/Exceptions.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/attributes/Exceptions.java deleted file mode 100644 index f88ceb84..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/classreader/attributes/Exceptions.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.classreader.attributes; - -import org.fife.rsta.ac.bsh.classreader.constantpool.ConstantClassInfo; -import org.fife.rsta.ac.bsh.classreader.constantpool.ConstantPoolInfo; -import org.fife.rsta.ac.bsh.classreader.ClassFile; -import org.fife.rsta.ac.bsh.classreader.MethodInfo; - - -/** - * Implementation of the "Exceptions" attribute found in - * {@link MethodInfo}s. - * - * @author Robert Futrell - * @version 1.0 - */ -public class Exceptions extends AttributeInfo { - - /** - * The method this attribute is describing. - */ - private MethodInfo mi; - - /** - * Indices into the constant pool of {@link ConstantClassInfo}s, each - * representing a class type that this method is declared to throw. - */ - private int[] exceptionIndexTable; - - - /** - * Constructor. - * - * @param mi The method this attribute is describing. - */ - public Exceptions(MethodInfo mi, int[] exceptionIndexTable) { - super(mi.getClassFile()); - this.exceptionIndexTable = exceptionIndexTable; - } - - - /** - * Returns the fully-qualified name of the specified exception. - * - * @param index The index of the exception whose name to retrieve. - * @return The name of the exception. - */ - public String getException(int index) { - ClassFile cf = getClassFile(); - ConstantPoolInfo cpi = cf.getConstantPoolInfo( - exceptionIndexTable[index]); - ConstantClassInfo cci = (ConstantClassInfo)cpi; - int nameIndex = cci.getNameIndex(); - String name = cf.getUtf8ValueFromConstantPool(nameIndex); - return name.replace('/', '.'); - } - - - /** - * Returns the number of exceptions this attribute knows about. - * - * @return The number of exceptions. - */ - public int getExceptionCount() { - return exceptionIndexTable==null ? 0 : exceptionIndexTable.length; - } - - - /** - * Returns information about the method this attribute is describing. - * - * @return The method information. - */ - public MethodInfo getMethodInfo() { - return mi; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/attributes/Signature.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/attributes/Signature.java deleted file mode 100644 index 8c711ac0..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/classreader/attributes/Signature.java +++ /dev/null @@ -1,424 +0,0 @@ -/* - * 01/16/2011 - * - * Copyright (C) 2011 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.classreader.attributes; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.fife.rsta.ac.bsh.classreader.ClassFile; -import org.fife.rsta.ac.bsh.classreader.MethodInfo; - - -/** - * The Signature attribute is an optional fixed-length attribute in the - * attribute table of the ClassFile, field_info and method_info - * structures.

    - * WARNING: This code is a complete mess. - * - * @author Robert Futrell - * @version 1.0 - */ -public class Signature extends AttributeInfo { - - private String signature; - - - public Signature(ClassFile cf, String signature) { - super(cf); - this.signature = signature; - } - - - public List getClassParamTypes() { - - List types = null; - - if (signature!=null && signature.startsWith("<")) { - - types = new ArrayList(1); // Usually a small number - int afterMatchingGT = skipLtGt(signature, 1); - - // We're assuming we don't come across corrupt signatures... - - String temp = signature.substring(1, afterMatchingGT-1); - int offs = 0; - int colon = temp.indexOf(':', offs); - while (offs-1) { - String ident = temp.substring(offs, colon); - int colonCount = 1; - char ch = temp.charAt(colon+colonCount); - if (ch==':') { // sometimes, there is another ':' - colonCount++; - ch = temp.charAt(colon+colonCount); - } - if (ch=='L') { // A ClassTypeSignature - int semicolon = temp.indexOf(';', colon+colonCount+1); - if (semicolon>-1) { - //String type = temp.substring(colon+2, semicolon); - // TODO: ... - types.add(ident); - offs = semicolon + 1; - colon = temp.indexOf(':', offs); - } - else { - System.err.println("WARN: Can't parse signature (1): " + signature); - break; - } - } - else { - System.err.println("WARN: Can't parse signature (2): " + signature); - break; - } - } - } - - return types; - - } - - - private int skipLtGt(String str, int start) { - - int ltCount = 1; - int offs = start; - - while (offs0) { - char ch = str.charAt(offs++); - switch (ch) { - case '<': - ltCount++; - break; - case '>': - ltCount--; - break; - } - } - - return offs; - - } - - - public List getMethodParamTypes(MethodInfo mi, ClassFile cf, - boolean qualified) { - - List paramTypeList = null; - String signature = this.signature; // Since we modify it - - if (signature!=null) { - - paramTypeList = new ArrayList(); - - // Handle "<...>", which essentially defines extra type args - Map additionalTypeArgs = null; - if (signature.charAt(0)=='<') { - int afterMatchingGT = skipLtGt(signature, 1); - String typeParams = signature.substring(1, afterMatchingGT-1); - additionalTypeArgs = parseAdditionalTypeArgs(typeParams); - signature = signature.substring(afterMatchingGT); - } - - if (signature.charAt(0)=='(') { - - int rparen = signature.indexOf(')', 1); - String paramDescriptors = signature.substring(1, rparen); - ParamDescriptorResult res = new ParamDescriptorResult(); - - while (paramDescriptors.length()>0) { - parseParamDescriptor(paramDescriptors, cf, additionalTypeArgs, - mi, "Error parsing method signature for ", res, qualified); - paramTypeList.add(res.type); - if(paramDescriptors.length()>res.pos) { - paramDescriptors = paramDescriptors.substring(res.pos); - } else { - break; - } - } - - } - - else { - System.out.println("TODO: Unhandled method signature for " + - mi.getName() + ": " + signature); - } - - } - - return paramTypeList; - - } - - - public String getMethodReturnType(MethodInfo mi, ClassFile cf, boolean qualified) { - - String signature = this.signature; // Since we modify it - String sig = null; - - if (signature!=null) { - - // Handle "<...>", which essentially defines extra type args - Map additionalTypeArgs = null; - if (signature.charAt(0)=='<') { - int afterMatchingGT = skipLtGt(signature, 1); - String typeParams = signature.substring(1, afterMatchingGT-1); - additionalTypeArgs = parseAdditionalTypeArgs(typeParams); - signature = signature.substring(afterMatchingGT); - } - - if (signature.charAt(0)=='(') { - int rparen = signature.indexOf(')', 1); - if (rparen>-1 && rparen<T> T[] toArray(T[] a)", where the - * "T" type parameter is the type of an argument passed - * to it). - * @return The type argument, or null if the given type - * parameter isn't defined. - */ - private String getTypeArgument(String typeVar, ClassFile cf, - Map additionalTypeArgs) { - String type = cf.getTypeArgument(typeVar); - if (type==null && additionalTypeArgs!=null) { - //type = (String)additionalTypeArgs.get(typeVar); - type = typeVar; - } - return type; - } - - - private Map parseAdditionalTypeArgs(String typeParams) { - - Map additionalTypeArgs = new HashMap(); - int offs = 0; - int colon = typeParams.indexOf(':', offs); - - while (offs-1 && lt additionalTypeArgs, - MethodInfo mi, String errorDesc, - ParamDescriptorResult res, boolean qualified) { - - // Can't do lastIndexOf() as there may be > 1 array parameter - // in the descriptors. - // int braceCount = str.lastIndexOf('[') + 1; - int braceCount = -1; - while (str.charAt(++braceCount) == '['); - int pos = braceCount; - String type = null; - boolean extendingGenericType = false; - - switch (str.charAt(pos)) { - - // BaseType - case 'B': - type = "byte"; - pos++; - break; - case 'C': - type = "char"; - pos++; - break; - case 'D': - type = "double"; - pos++; - break; - case 'F': - type = "float"; - pos++; - break; - case 'I': - type = "int"; - pos++; - break; - case 'J': - type = "long"; - pos++; - break; - case 'S': - type = "short"; - pos++; - break; - case 'Z': - type = "boolean"; - pos++; - break; - - // ObjectType - case 'L': - int semicolon = str.indexOf(';', pos+1); - int lt = str.indexOf('<', pos+1); - if (lt>-1 && lt paramTypeList = new ArrayList(); - // Recursively parse type parameters of this parameter - while (paramDescriptors.length()>0) { - parseParamDescriptor(paramDescriptors, cf, additionalTypeArgs, - mi, "Error parsing method signature for ", res2, qualified); - paramTypeList.add(res2.type); - if(paramDescriptors.length()>res2.pos) { - paramDescriptors = paramDescriptors.substring(res2.pos); - } else { - break; - } - - } - StringBuilder sb = new StringBuilder(type).append('<'); - for (int i=0; i').toString(); - pos = offs+1;//semicolon + 1; Skip semicolon that came AFTER "<...>" - } - } - else { - String clazz = str.substring(pos + 1, semicolon); - //clazz = org.fife.rsta.ac.java.Util.replaceChar(clazz, '/', '.'); - //clazz = clazz.substring(clazz.lastIndexOf('/')+1); - clazz = qualified ? clazz.replace('/', '.') : clazz.substring(clazz.lastIndexOf('/')+1); - type = clazz; - pos += semicolon + 1; - } - break; - - case '+': // "super extends T" - extendingGenericType = true; - pos++; - // Fall through - - case 'T': // Generic type - semicolon = str.indexOf(';', pos+1); - String typeVar = str.substring(pos+1, semicolon); - type = getTypeArgument(typeVar, cf, additionalTypeArgs); - if (type==null) { - type = "UNKNOWN_GENERIC_TYPE_" + typeVar; - } - else if (extendingGenericType) { - type = "? extends " + type; - } - pos = semicolon + 1; - break; - - case '*': - type = "?"; - pos++; - break; - - // Invalid method descriptor - default: - String temp = "INVALID_TYPE_" + str; - type = temp; - pos += str.length(); - break; - - } - - for (int i = 0; i < braceCount; i++) { - type += "[]"; - } - - return res.set(type, pos); - - } - - - @Override - public String toString() { - return "[Signature: signature=" + getSignature() + "]"; - } - - - private static class ParamDescriptorResult { - - public String type; - public int pos; - - public ParamDescriptorResult set(String type, int pos) { - this.type = type; - this.pos = pos; - return this; - } - - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/attributes/SourceFile.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/attributes/SourceFile.java deleted file mode 100644 index 3b0a2592..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/classreader/attributes/SourceFile.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.classreader.attributes; - -import org.fife.rsta.ac.bsh.classreader.ClassFile; - - -/** - * The SourceFile attribute, an optional fixed-length attribute - * in the attributes table of a {@link ClassFile}. There can be no more than - * one SourceFile attribute for a given ClassFile. - * - * @author Robert Futrell - * @version 1.0 - */ -public class SourceFile extends AttributeInfo { - - /** - * Index into the constant pool of a {@link ConstantUtf8Info} structure - * representing the name of the source file from which this class file - * was compiled. - */ - private int sourceFileIndex; - - - /** - * Constructor. - * - * @param cf The class file. - * @param sourceFileIndex Index into the constant pool of a - * {@link ConstantUtf8Info} structure representing the source file - * name. - */ - public SourceFile(ClassFile cf, int sourceFileIndex) { - super(cf); - this.sourceFileIndex = sourceFileIndex; - } - - - /** - * Returns the name of the source file that was compiled to create this - * class file. - * - * @return The name of the source file. - */ - public String getSourceFileName() { - return getClassFile().getUtf8ValueFromConstantPool(sourceFileIndex); - } - - - /** - * Returns a string representation of this attribute. Useful for - * debugging. - * - * @return A string representation of this attribute. - */ - @Override - public String toString() { - return "[SourceFile: " + - "file=" + getSourceFileName() + - "]"; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/attributes/UnsupportedAttribute.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/attributes/UnsupportedAttribute.java deleted file mode 100644 index 1c4d5ba5..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/classreader/attributes/UnsupportedAttribute.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.classreader.attributes; - -import org.fife.rsta.ac.bsh.classreader.ClassFile; - - -/** - * An attribute that is unknown/unsupported by this decompiler. - * - * @author Robert Futrell - * @version 1.0 - */ -public class UnsupportedAttribute extends AttributeInfo { - - private String name; - //private int[] info; - - - /** - * Constructor. - * - * @param cf The class file. - */ - public UnsupportedAttribute(ClassFile cf, String name/*, int[] info*/) { - super(cf); - this.name = name; - //this.info = info; - } - -/* - public int[] getInfo() { - return info; - } -*/ - - @Override - public String getName() { - return name; - } - - - /** - * Returns a string representation of this attribute. Useful for - * debugging. - * - * @return A string representation of this attribute. - */ - @Override - public String toString() { - return "[UnsupportedAttribute: " + - "name=" + getName() + - "]"; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantClassInfo.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantClassInfo.java deleted file mode 100644 index 59ebc3b5..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantClassInfo.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.classreader.constantpool; - - -/** - * Represents a class or interface. - * - * @author Robert Futrell - * @version 1.0 - */ -public class ConstantClassInfo extends ConstantPoolInfo { - - /** - * An index into the constant_pool table. The entry at this index - * must be a CONSTANT_Utf8_info structure representing - * a valid, fully-qualified class or interface name encoded in internal - * form. - */ - private int nameIndex; - - - /** - * Constructor. - * - * @param nameIndex The index into the constant pool containing a - * {@link ConstantUtf8Info} representing the fully-qualified - * class or interface name, encoded in internal form. - */ - public ConstantClassInfo(int nameIndex) { - super(CONSTANT_Class); - this.nameIndex = nameIndex; - } - - - /** - * Returns the index into the constant pool table for a - * ConstantUtf8Info structure representing a valid, - * fully-qualified class or interface name, encoded in internal form. - * - * @return The index into the constant pool table. - */ - public int getNameIndex() { - return nameIndex; - } - - - /** - * Returns a string representation of this object. Useful for debugging. - * - * @return A string representation of this object. - */ - @Override - public String toString() { - return "[ConstantClassInfo: " + - "nameIndex=" + getNameIndex() + - "]"; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantDoubleInfo.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantDoubleInfo.java deleted file mode 100644 index 59d17748..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantDoubleInfo.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.classreader.constantpool; - - -/** - * Class corresponding to the CONSTANT_Double_info structure. - * - * @author Robert Futrell - * @version 1.0 - */ -public class ConstantDoubleInfo extends ConstantPoolInfo { - - private int highBytes; - private int lowBytes; - - - /** - * Constructor. - * - * @param highBytes - * @param lowBytes - */ - public ConstantDoubleInfo(int highBytes, int lowBytes) { - super(CONSTANT_Double); - this.highBytes = highBytes; - this.lowBytes = lowBytes; - } - - - /** - * Returns the double value represented by this constant. - * - * @return The double value. - */ - public double getDoubleValue() { - long bits = (((long)highBytes<<32)) + lowBytes; - return Double.longBitsToDouble(bits); - } - - - public int getHighBytes() { - return highBytes; - } - - - public int getLowBytes() { - return lowBytes; - } - - - /** - * Returns a string representation of this object. Useful for debugging. - * - * @return A string representation of this object. - */ - @Override - public String toString() { - return "[ConstantDoubleInfo: " + - "value=" + getDoubleValue() + - "]"; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantFieldrefInfo.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantFieldrefInfo.java deleted file mode 100644 index 5d15b84b..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantFieldrefInfo.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.classreader.constantpool; - - -/** - * Class corresponding to a CONSTANT_Fieldref_info structure. - * - * @author Robert Futrell - * @version 1.0 - */ -public class ConstantFieldrefInfo extends ConstantPoolInfo { - - private int classIndex; - - private int nameAndTypeIndex; - - - /** - * Constructor. - * - * @param classIndex - * @param nameAndTypeIndex - */ - public ConstantFieldrefInfo(int classIndex, int nameAndTypeIndex) { - super(CONSTANT_Fieldref); - this.classIndex = classIndex; - this.nameAndTypeIndex = nameAndTypeIndex; - } - - - public int getClassIndex() { - return classIndex; - } - - - public int getNameAndTypeIndex() { - return nameAndTypeIndex; - } - - - /** - * Returns a string representation of this object. Useful for debugging. - * - * @return A string representation of this object. - */ - @Override - public String toString() { - return "[ConstantFieldrefInfo: " + - "classIndex=" + getClassIndex() + - "; nameAndTypeIndex=" + getNameAndTypeIndex() + - "]"; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantFloatInfo.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantFloatInfo.java deleted file mode 100644 index 22a71bcf..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantFloatInfo.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.classreader.constantpool; - - -/** - * Class corresponding to the CONSTANT_Float_info structure. - * - * @author Robert Futrell - * @version 1.0 - */ -public class ConstantFloatInfo extends ConstantPoolInfo { - - private int bytes; // u4 - - - /** - * Constructor. - * - * @param bytes - */ - public ConstantFloatInfo(int bytes) { - super(CONSTANT_Float); - this.bytes = bytes; - } - - - public long getBytes() { - return bytes; - } - - - /** - * Returns the float value represented. - * - * @return The float value. - */ - public float getFloatValue() { - return Float.intBitsToFloat(bytes); - } - - - /** - * Returns a string representation of this object. Useful for debugging. - * - * @return A string representation of this object. - */ - @Override - public String toString() { - return "[ConstantFloatInfo: " + - "value=" + getFloatValue() + - "]"; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantIntegerInfo.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantIntegerInfo.java deleted file mode 100644 index 0236218d..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantIntegerInfo.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.classreader.constantpool; - - -/** - * Class corresponding to the CONSTANT_Integer_info structure. - * - * @author Robert Futrell - * @version 1.0 - */ -public class ConstantIntegerInfo extends ConstantPoolInfo { - - private long bytes; // u4 - - - /** - * Constructor. - */ - public ConstantIntegerInfo(long bytes) { - super(CONSTANT_String); - this.bytes = bytes; - } - - - public long getBytes() { - return bytes; - } - - - /** - * Returns the intrepresented by this info. - * - * @return The int represented. - */ - public int getIntValue() { - return (int)bytes; - } - - - /** - * Returns a string representation of this object. Useful for debugging. - * - * @return A string representation of this object. - */ - @Override - public String toString() { - return "[ConstantIntegerInfo: " + - "bytes=" + getBytes() + - "]"; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantInterfaceMethodrefInfo.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantInterfaceMethodrefInfo.java deleted file mode 100644 index 59c4ae7c..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantInterfaceMethodrefInfo.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.classreader.constantpool; - - -/** - * Class corresponding to a CONSTANT_InterfaceMethodref_info - * structure. - * - * @author Robert Futrell - * @version 1.0 - */ -class ConstantInterfaceMethodrefInfo extends ConstantPoolInfo { - - - private int classIndex; - - private int nameAndTypeIndex; - - - /** - * Constructor. - * - * @param classIndex - * @param nameAndTypeIndex - */ - public ConstantInterfaceMethodrefInfo(int classIndex, int nameAndTypeIndex){ - super(CONSTANT_InterfaceMethodref); - this.classIndex = classIndex; - this.nameAndTypeIndex = nameAndTypeIndex; - } - - - public int getClassIndex() { - return classIndex; - } - - - public int getNameAndTypeIndex() { - return nameAndTypeIndex; - } - - - /** - * Returns a string representation of this object. Useful for debugging. - * - * @return A string representation of this object. - */ - @Override - public String toString() { - return "[ConstantInterfaceMethodrefInfo: " + - "classIndex=" + getClassIndex() + - "; nameAndTypeIndex=" + getNameAndTypeIndex() + - "]"; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantInvokeDynamicInfo.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantInvokeDynamicInfo.java deleted file mode 100644 index c0d89c0c..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantInvokeDynamicInfo.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.classreader.constantpool; - -/** - * Class representing a CONSTANT_InvokeDynamic_info structure. - * - * @author Robert Futrell - * @version 1.0 - */ -public class ConstantInvokeDynamicInfo extends ConstantPoolInfo { - - private int bootstrapMethodAttrIndex; - - private int nameAndTypeIndex; - - - /** - * Constructor. - * - * @param bootstrapMethodAttrIndex - * @param nameAndTypeIndex - */ - public ConstantInvokeDynamicInfo(int bootstrapMethodAttrIndex, int nameAndTypeIndex) { - super(CONSTANT_InvokeDynamic); - this.bootstrapMethodAttrIndex = bootstrapMethodAttrIndex; - this.nameAndTypeIndex = nameAndTypeIndex; - } - - - public int getBootstrapMethodAttrIndex() { - return bootstrapMethodAttrIndex; - } - - - public int getNameAndTypeIndex() { - return nameAndTypeIndex; - } - - - /** - * Returns a string representation of this object. Useful for debugging. - * - * @return A string representation of this object. - */ - @Override - public String toString() { - return "[ConstantInvokeDynamicInfo: " + - "bootstrapMethodAttrIndex=" + getBootstrapMethodAttrIndex() + - "; nameAndTypeIndex=" + getNameAndTypeIndex() + - "]"; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantLongInfo.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantLongInfo.java deleted file mode 100644 index 30d189ff..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantLongInfo.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.classreader.constantpool; - - -/** - * Class corresponding to the CONSTANT_Long_info structure. - * - * @author Robert Futrell - * @version 1.0 - */ -public class ConstantLongInfo extends ConstantPoolInfo { - - private int highBytes; // u4 - private int lowBytes; // u4 - - - /** - * Constructor. - * - * @param highBytes - * @param lowBytes - */ - public ConstantLongInfo(int highBytes, int lowBytes) { - super(CONSTANT_Long); - this.highBytes = highBytes; - this.lowBytes = lowBytes; - } - - - public int getHighBytes() { - return highBytes; - } - - - public long getLongValue() { - return (((long)highBytes<<32)) + lowBytes; - } - - - public int getLowBytes() { - return lowBytes; - } - - - /** - * Returns a string representation of this object. Useful for debugging. - * - * @return A string representation of this object. - */ - @Override - public String toString() { - return "[ConstantLongInfo: " + - "value=" + getLongValue() + - "]"; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantMethodHandleInfo.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantMethodHandleInfo.java deleted file mode 100644 index 56cda546..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantMethodHandleInfo.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.classreader.constantpool; - -/** - * Class representing a CONSTANT_MethodHandle structure. - * - * @author Robert Futrell - * @version 1.0 - */ -public class ConstantMethodHandleInfo extends ConstantPoolInfo { - - private int referenceKind; - - private int referenceIndex; - - - /** - * Constructor. - * - * @param referenceKind - * @param referenceIndex - */ - public ConstantMethodHandleInfo(int referenceKind, int referenceIndex) { - super(CONSTANT_MethodHandle); - this.referenceKind = referenceKind; - this.referenceIndex = referenceIndex; - } - - - public int getReferenceKind() { - return referenceKind; - } - - public int getReferenceIndex() { - return referenceIndex; - } - - - /** - * Returns a string representation of this object. Useful for debugging. - * - * @return A string representation of this object. - */ - @Override - public String toString() { - return "[ConstantMethodHandleInfo: " + - "referenceKind=" + getReferenceKind() + - "; referenceIndex=" + getReferenceIndex() + - "]"; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantMethodTypeInfo.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantMethodTypeInfo.java deleted file mode 100644 index aa4a17aa..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantMethodTypeInfo.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.classreader.constantpool; - -/** - * Class representing a CONSTANT_MethodType structure. - * - * @author Robert Futrell - * @version 1.0 - */ -public class ConstantMethodTypeInfo extends ConstantPoolInfo { - - private int descriptorIndex; - - /** - * Constructor. - * - * @param descriptorIndex - */ - public ConstantMethodTypeInfo(int descriptorIndex) { - super(CONSTANT_MethodType); - this.descriptorIndex = descriptorIndex; - } - - - public int getDescriptorIndex() { - return descriptorIndex; - } - - - /** - * Returns a string representation of this object. Useful for debugging. - * - * @return A string representation of this object. - */ - @Override - public String toString() { - return "[ConstantMethodTypeInfo: " + - "bootstrapMethodAttrIndex=" + getDescriptorIndex() + - "]"; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantMethodrefInfo.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantMethodrefInfo.java deleted file mode 100644 index 3eccab9a..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantMethodrefInfo.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.classreader.constantpool; - - -/** - * Class corresponding to a CONSTANT_Methodref_info structure. - * - * @author Robert Futrell - * @version 1.0 - */ -public class ConstantMethodrefInfo extends ConstantPoolInfo { - - private int classIndex; - - private int nameAndTypeIndex; - - - /** - * Constructor. - * - * @param classIndex - * @param nameAndTypeIndex - */ - public ConstantMethodrefInfo(int classIndex, int nameAndTypeIndex) { - super(CONSTANT_Methodref); - this.classIndex = classIndex; - this.nameAndTypeIndex = nameAndTypeIndex; - } - - - public int getClassIndex() { - return classIndex; - } - - - public int getNameAndTypeIndex() { - return nameAndTypeIndex; - } - - - /** - * Returns a string representation of this object. Useful for debugging. - * - * @return A string representation of this object. - */ - @Override - public String toString() { - return "[ConstantMethodrefInfo: " + - "classIndex=" + getClassIndex() + - "; nameAndTypeIndex=" + getNameAndTypeIndex() + - "]"; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantNameAndTypeInfo.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantNameAndTypeInfo.java deleted file mode 100644 index 893d3e79..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantNameAndTypeInfo.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.classreader.constantpool; - - -/** - * Class representing a CONSTANT_NameAndType_info structure. - * - * @author Robert Futrell - * @version 1.0 - */ -public class ConstantNameAndTypeInfo extends ConstantPoolInfo { - - private int nameIndex; - private int descriptorIndex; - - - /** - * Constructor. - * - * @param nameIndex - * @param descriptorIndex - */ - public ConstantNameAndTypeInfo(int nameIndex, int descriptorIndex) { - super(CONSTANT_NameAndType); - this.nameIndex = nameIndex; - this.descriptorIndex = descriptorIndex; - } - - - public int getDescriptorIndex() { - return descriptorIndex; - } - - - public int getNameIndex() { - return nameIndex; - } - - - /** - * Returns a string representation of this object. Useful for debugging. - * - * @return A string representation of this object. - */ - @Override - public String toString() { - return "[ConstantNameAndTypeInfo: " + - "descriptorIndex=" + getDescriptorIndex() + - "; nameIndex=" + getNameIndex() + - "]"; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantPoolInfo.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantPoolInfo.java deleted file mode 100644 index 63bfe8c5..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantPoolInfo.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.classreader.constantpool; - - -/** - * A ConstantPool table entry.

    - * - * See - * http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html#20080 - * for more information. - * - * @author Robert Futrell - * @version 1.0 - */ -public abstract class ConstantPoolInfo implements ConstantTypes { - - private int tag; - - - /** - * Constructor. - */ - public ConstantPoolInfo(int tag) { - this.tag = tag; - } - - - /** - * Returns the tag item for this structure. - * - * @return The tag item. - */ - public int getTag() { - return tag; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantPoolInfoFactory.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantPoolInfoFactory.java deleted file mode 100644 index 1865f16d..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantPoolInfoFactory.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.classreader.constantpool; - -import org.fife.rsta.ac.bsh.classreader.ClassFile; -import java.io.DataInputStream; -import java.io.IOException; - - - -public class ConstantPoolInfoFactory implements ConstantTypes { - - - /** - * Private constructor to prevent instantiation. - */ - private ConstantPoolInfoFactory() { - } - - - public static ConstantPoolInfo readConstantPoolInfo(ClassFile cf, - DataInputStream in) throws IOException { - - ConstantPoolInfo cpi = null; - int tag = in.read(); - - switch (tag) { - - case CONSTANT_Class: - int nameIndex = in.readUnsignedShort(); - cpi = new ConstantClassInfo(nameIndex); - break; - - case CONSTANT_Double: - int highBytes = in.readInt(); - int lowBytes = in.readInt(); - cpi = new ConstantDoubleInfo(highBytes, lowBytes); - break; - - case CONSTANT_Fieldref: - int classIndex = in.readUnsignedShort(); - int nameAndTypeIndex = in.readUnsignedShort(); - cpi = new ConstantFieldrefInfo(classIndex, nameAndTypeIndex); - break; - - case CONSTANT_Float: - int bytes = in.readInt(); - cpi = new ConstantFloatInfo(bytes); - break; - - case CONSTANT_Integer: - bytes = in.readInt(); - cpi = new ConstantIntegerInfo(bytes); - break; - - case CONSTANT_InterfaceMethodref: - classIndex = in.readUnsignedShort(); - nameAndTypeIndex = in.readUnsignedShort(); - cpi = new ConstantInterfaceMethodrefInfo(classIndex, nameAndTypeIndex); - break; - - case CONSTANT_Long: - highBytes = in.readInt(); - lowBytes = in.readInt(); - cpi = new ConstantLongInfo(highBytes, lowBytes); - break; - - case CONSTANT_Methodref: - classIndex = in.readUnsignedShort(); - nameAndTypeIndex = in.readUnsignedShort(); - cpi = new ConstantMethodrefInfo(classIndex, nameAndTypeIndex); - break; - - case CONSTANT_NameAndType: - nameIndex = in.readUnsignedShort(); - int descriptorIndex = in.readUnsignedShort(); - cpi = new ConstantNameAndTypeInfo(nameIndex, descriptorIndex); - break; - - case CONSTANT_String: - int stringIndex = in.readUnsignedShort(); - cpi = new ConstantStringInfo(cf, stringIndex); - break; - - case CONSTANT_Utf8: - int count = in.readUnsignedShort(); - byte[] byteArray = new byte[count]; - in.readFully(byteArray); - cpi = new ConstantUtf8Info(byteArray); - break; - - case CONSTANT_MethodHandle: - int referenceKind = in.read(); - int referenceIndex = in.readUnsignedShort(); - cpi = new ConstantMethodHandleInfo(referenceKind, referenceIndex); - break; - - case CONSTANT_MethodType: - descriptorIndex = in.readUnsignedShort(); - cpi = new ConstantMethodTypeInfo(descriptorIndex); - break; - - case CONSTANT_InvokeDynamic: - int bootstrapMethodAttrIndex = in.readUnsignedShort(); - nameAndTypeIndex = in.readUnsignedShort(); - cpi = new ConstantInvokeDynamicInfo(bootstrapMethodAttrIndex, nameAndTypeIndex); - break; - - default: - throw new IOException("Unknown tag for constant pool info: " + tag); - - } - - return cpi; - - } - - -} diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantStringInfo.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantStringInfo.java deleted file mode 100644 index e80bbe8b..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantStringInfo.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.classreader.constantpool; - -import org.fife.rsta.ac.bsh.classreader.ClassFile; - - -/** - * Class corresponding to the CONSTANT_String_info structure. - * - * @author Robert Futrell - * @version 1.0 - */ -public class ConstantStringInfo extends ConstantPoolInfo { - - private ClassFile cf; - private int stringIndex; - - - /** - * Constructor. - * - * @param stringIndex - */ - public ConstantStringInfo(ClassFile cf, int stringIndex) { - super(CONSTANT_String); - this.cf = cf; - this.stringIndex = stringIndex; - } - - - public int getStringIndex() { - return stringIndex; - } - - - /** - * Returns the string represented by this constant. - * - * @return The string value represented. - */ - public String getStringValue() { - return '"' + cf.getUtf8ValueFromConstantPool(getStringIndex()) + '"'; - - } - - - /** - * Returns a string representation of this object. Useful for debugging. - * - * @return A string representation of this object. - */ - @Override - public String toString() { - return "[ConstantStringInfo: " + - "stringIndex=" + getStringIndex() + - "]"; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantTypes.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantTypes.java deleted file mode 100644 index 12dd687c..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantTypes.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.classreader.constantpool; - - -/** - * Constant types used by {@link ConstantPoolInfo}s. - * - * @author Robert Futrell - * @version 1.0 - */ -interface ConstantTypes { - - public static final int CONSTANT_Class = 7; - - public static final int CONSTANT_Fieldref = 9; - - public static final int CONSTANT_Methodref = 10; - - public static final int CONSTANT_InterfaceMethodref = 11; - - public static final int CONSTANT_String = 8; - - public static final int CONSTANT_Integer = 3; - - public static final int CONSTANT_Float = 4; - - public static final int CONSTANT_Long = 5; - - public static final int CONSTANT_Double = 6; - - public static final int CONSTANT_NameAndType = 12; - - public static final int CONSTANT_Utf8 = 1; - - public static final int CONSTANT_MethodHandle = 15; - - public static final int CONSTANT_MethodType = 16; - - public static final int CONSTANT_InvokeDynamic = 18; - -} diff --git a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantUtf8Info.java b/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantUtf8Info.java deleted file mode 100644 index 133372ef..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/classreader/constantpool/ConstantUtf8Info.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.classreader.constantpool; - -import java.io.UnsupportedEncodingException; - - -/** - * Class representing a CONSTANT_Utf8_info structure. - * - * @author Robert Futrell - * @version 1.0 - */ -public class ConstantUtf8Info extends ConstantPoolInfo { - - //private byte[] bytes; - private String representedString; - - - /** - * Constructor. - */ - public ConstantUtf8Info(byte[] bytes) { - super(CONSTANT_Utf8); - //this.bytes = bytes; - representedString = createRepresentedString(bytes); - } - - -// public byte[] getBytes() { -// return bytes; -// } - -/* - private static final boolean isBitSet(int b, int bit) { - return ((b>>bit)&1)>0; - } -*/ - - private String createRepresentedString(byte[] bytes) { -/* - StringBuilder sb = new StringBuilder(); - - int pos = 0; - while (pos>5)) { - // x = 110 (bits 10-6) - // y = 10 (bits 5-0) - // ch = ((x & 0x1f) << 6) + (y & 0x3f) - int x = b; - int y = bytes[pos++]; - char ch = (char)(((x&0x1f)<<6) + (y&0x3f)); - sb.append(ch); - } - - // chars in range '\u0800' - '\uFFFF'. - else if (15==(b>>4)) { - // x = 1110 (bits 15-12) - // y = 10 (bits 11-6) - // z = 10 (bits 5-0) - // ch = ((x & 0xf) << 12) + ((y & 0x3f) << 6) + (z & 0x3f) - int x = b; - int y = bytes[pos++]; - int z = bytes[pos++]; - char ch = (char)(((x&0xf)<<12) + ((y&0x3f)<<6) + (z&0x3f)); - sb.append(ch); - } - - // An unknown bit header. - else { - throw new InternalError("Unknown bit header in Utf8 string: " + - b); - } - - } - - representedString = sb.toString(); -*/ -try { - representedString = new String(bytes, "UTF-8"); -} catch (UnsupportedEncodingException uee) { // Never happens. - uee.printStackTrace(); - System.exit(0); -} - return representedString; - - } - - - /** - * Returns the string represented by this info. - * - * @param quoted Whether to add enclosing quotation marks, and "escape" - * any quotation marks in the represented string. - * @return The string represented. - */ - public String getRepresentedString(boolean quoted) { - if (!quoted) { - return representedString; - } - String temp = "\"" + representedString.replaceAll("\"", "\\\"") + "\""; - return temp; - } - - - /** - * Returns a string representation of this object. Useful for debugging. - * - * @return A string representation of this object. - */ - @Override - public String toString() { - return "[ConstantUtf8Info: " + representedString + - "]"; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/ASTNode.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/ASTNode.java deleted file mode 100644 index dc362c0c..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/ASTNode.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.rjc.ast; - - -/** - * A node in a Java AST. - * - * @author Robert Futrell - * @version 1.0 - */ -public interface ASTNode { - - - /** - * Returns the "name" of this node. This will be the name of the method, - * the name of the member or local variable, etc. For {@link CodeBlock}s - * it will be {@link CodeBlock#NAME}.

    - * - * Note that this may not be unique. For example, a class with an - * overloaded method will have multiple methods with the same "name," - * just with different signatures. - * - * @return The "name" of this node. - */ - public String getName(); - - - /** - * Returns the end offset of the "name" of this node. - * - * @return The end offset. - */ - public int getNameEndOffset(); - - - /** - * Returns the start offset of the "name" of this node. - * - * @return The start offset. - */ - public int getNameStartOffset(); - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/AbstractASTNode.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/AbstractASTNode.java deleted file mode 100644 index b5fbdfd3..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/AbstractASTNode.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.rjc.ast; - -import org.fife.rsta.ac.bsh.rjc.lexer.Offset; - - -/** - * Base implementation of an AST node. - * - * @author Robert Futrell - * @version 1.0 - */ -abstract class AbstractASTNode implements ASTNode { - - private String name; - private Offset startOffs; - private Offset endOffs; - - - protected AbstractASTNode(String name, Offset start) { - this(name, start, null); - } - - - protected AbstractASTNode(String name, Offset start, Offset end) { - this.name = name; - startOffs = start; - endOffs = end; - } - - - /** - * {@inheritDoc} - */ - public String getName() { - return name; - } - - - /** - * {@inheritDoc} - */ - public int getNameEndOffset() { - return endOffs!=null ? endOffs.getOffset() : Integer.MAX_VALUE; - } - - - /** - * {@inheritDoc} - */ - public int getNameStartOffset() { - return startOffs!=null ? startOffs.getOffset() : 0; - } - - - public void setDeclarationEndOffset(Offset end) { - endOffs = end; - } - - - /** - * Sets the start and end offsets of this node. - * - * @param start The start offset. - * @param end The end offset. - */ - protected void setDeclarationOffsets(Offset start, Offset end) { - startOffs = start; - endOffs = end; - } - - - /** - * Returns the name of this node (e.g. the value of {@link #getName()}. - * Subclasses can override this method if appropriate. - * - * @return A string representation of this node. - */ - @Override - public String toString() { - return getName(); - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/AbstractMember.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/AbstractMember.java deleted file mode 100644 index d4ce3513..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/AbstractMember.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 04/29/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.rjc.ast; - -import org.fife.rsta.ac.bsh.rjc.lang.Modifiers; -import org.fife.rsta.ac.bsh.rjc.lexer.Offset; - - -/** - * Code shared amongst all {@link Member} nodes. - * - * @author Robert Futrell - * @version 1.0 - */ -abstract class AbstractMember extends AbstractASTNode implements Member { - - private TypeDeclaration parentTypeDec; - - - protected AbstractMember(String name, Offset start) { - super(name, start); - } - - - protected AbstractMember(String name, Offset start, Offset end) { - super(name, start, end); - } - - - public TypeDeclaration getParentTypeDeclaration() { - return parentTypeDec; - } - - - /** - * {@inheritDoc} - */ - public boolean isStatic() { - Modifiers modifiers = getModifiers(); - return modifiers!=null && modifiers.isStatic(); - } - - - /** - * {@inheritDoc} - */ - public void setParentTypeDeclaration(TypeDeclaration dec) { - if (dec==null) { - throw new InternalError("Parent TypeDeclaration cannot be null"); - } - parentTypeDec = dec; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/AbstractTypeDeclarationNode.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/AbstractTypeDeclarationNode.java deleted file mode 100644 index a0cc9bfe..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/AbstractTypeDeclarationNode.java +++ /dev/null @@ -1,288 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.rjc.ast; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.fife.rsta.ac.bsh.rjc.lang.Modifiers; -import org.fife.rsta.ac.bsh.rjc.lexer.Offset; - - -public abstract class AbstractTypeDeclarationNode extends AbstractASTNode - implements TypeDeclaration { - - private Package pkg; - private Modifiers modifiers; - private TypeDeclaration parentType; - private List childTypes; - private Offset bodyStartOffs; - private Offset bodyEndOffs; - private boolean deprecated; - private String docComment; - - // --- "ClassBody"/"InterfaceBody"/EnumConstant fields --- - private List memberList; - - - public AbstractTypeDeclarationNode(String name, Offset start) { - super(name, start); - init(); - } - - - public AbstractTypeDeclarationNode(String name, Offset start, Offset end) { - super(name, start, end); - init(); - } - - - public void addMember(Member member) { - member.setParentTypeDeclaration(this); - memberList.add(member); - } - - - public void addTypeDeclaration(TypeDeclaration type) { - if (childTypes==null) { - childTypes = new ArrayList(1); // Usually small - } - type.setParentType(this); - childTypes.add(type); - } - - - public boolean getBodyContainsOffset(int offs) { - return offs>=getBodyStartOffset() && offs getFieldIterator() { - List fields = new ArrayList(); - for (Iterator i=getMemberIterator(); i.hasNext(); ) { - Member member = i.next(); - if (member instanceof Field) { - fields.add((Field)member); - } - } - return fields.iterator(); - } - - - public Member getMember(int index) { - return memberList.get(index); - } - - - public int getMemberCount() { - return memberList.size(); - } - - - /** - * {@inheritDoc} - */ - public Iterator getMemberIterator() { - return memberList.iterator(); - } - - - /** - * {@inheritDoc} - */ - public Iterator getMethodIterator() { - List methods = new ArrayList(); - for (Iterator i=getMemberIterator(); i.hasNext(); ) { - Member member = i.next(); - if (member instanceof Method) { - methods.add((Method)member); - } - } - return methods.iterator(); - } - - - /** - * {@inheritDoc} - */ - public List getMethodsByName(String name) { - List methods = new ArrayList(); - for (Iterator i=getMemberIterator(); i.hasNext(); ) { - Member member = i.next(); - if (member instanceof Method && name.equals(member.getName())) { - methods.add((Method)member); - } - } - return methods; - } - - - public Modifiers getModifiers() { - return modifiers; - } - - - /** - * {@inheritDoc} - */ - public String getName(boolean fullyQualified) { - String name = getName(); - if (fullyQualified) { - Package pkg = getPackage(); - if (pkg!=null) { - name = pkg.getName() + "." + name; - } - } - return name; - } - - - /** - * {@inheritDoc} - */ - public Package getPackage() { - return pkg; - } - - - /** - * {@inheritDoc} - */ - public TypeDeclaration getParentType() { - return parentType; - } - - - private void init() { - memberList = new ArrayList(); - } - - - public boolean isDeprecated() { - return deprecated; - } - - - /** - * {@inheritDoc} - */ - public boolean isStatic() { - return modifiers==null ? false : modifiers.isStatic(); - } - - - public void setBodyEndOffset(Offset end) { - bodyEndOffs = end; - } - - - public void setBodyStartOffset(Offset start) { - bodyStartOffs = start; - } - - - public void setDeprecated(boolean deprecated) { - this.deprecated = deprecated; - } - - - public void setDocComment(String comment) { - docComment = comment; - } - - - public void setModifiers(Modifiers modifiers) { - this.modifiers = modifiers; - } - - - /** - * Sets the package this type is in. - * - * @param pkg The package, or null if this is in the - * default package. - * @see #getPackage() - */ - public void setPackage(Package pkg) { - this.pkg = pkg; - } - - - /** - * {@inheritDoc} - */ - public void setParentType(TypeDeclaration parentType) { - this.parentType = parentType; - } - - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - if (modifiers!=null) { - sb.append(modifiers.toString()).append(' '); - } - sb.append(getTypeString()).append(' '); - sb.append(getName()); - return sb.toString(); - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/CodeBlock.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/CodeBlock.java deleted file mode 100644 index f4c5076d..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/CodeBlock.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.rjc.ast; - -import java.util.ArrayList; -import java.util.List; - -import org.fife.rsta.ac.bsh.rjc.lang.Modifiers; -import org.fife.rsta.ac.bsh.rjc.lang.Type; -import org.fife.rsta.ac.bsh.rjc.lexer.Offset; -import org.fife.rsta.ac.bsh.rjc.lexer.TokenTypes; - - -/** - * A block of code in curly braces in a class.

    - * - * This class implements the Member interface because a block - * can be a member (say, a static block in a class declaration), but usually - * it's not actually a Member, but something else, e.g. the body - * of a method, or the content of an if-statement, etc. - * - * @author Robert Futrell - * @version 1.0 - */ -public class CodeBlock extends AbstractMember { - - /** - * The name of all CodeBlocks. - */ - public static final String NAME = "{...}"; - - private CodeBlock parent; - private List children; - private List localVars; - private boolean isStatic; - - - public CodeBlock(boolean isStatic, Offset startOffs) { - super(NAME, startOffs); - this.isStatic = isStatic; - } - - - public void add(CodeBlock child) { - if (children==null) { - children = new ArrayList(); - } - children.add(child); - child.setParent(this); - } - - - public void addLocalVariable(LocalVariable localVar) { - if (localVars==null) { - localVars = new ArrayList(); - } - localVars.add(localVar); - } - - - public boolean containsOffset(int offs) { - // Do endOffset first since we'll often iterate from first CodeBlock - // to last, so checking it first should be faster. - return getNameEndOffset()>=offs && getNameStartOffset()<=offs; - } - - - public CodeBlock getChildBlock(int index) { - return children.get(index); - } - - - public int getChildBlockCount() { - return children==null ? 0 : children.size(); - } - - - /** - * Returns the deepest code block nested under this one (or this one - * itself) containing a given offset. - * - * @param offs The offset to look for. - * @return The deepest-nested code block containing the offset, or - * null if this code block and none of its children - * contain the offset. - */ - public CodeBlock getDeepestCodeBlockContaining(int offs) { - if (!containsOffset(offs)) { - return null; - } - for (int i=0; i getLocalVarsBefore(int offs) { - - List vars = new ArrayList(); - - if (localVars!=null) { - for (int i=0; inull, since blocks don't have types. - * - * @return null always. - */ - public Type getType() { - return null; - } - - - public boolean isDeprecated() { - return false; - } - - - /** - * Returns whether this block is a static block (in a class declaration). - * - * @return Whether this is a static code block. - */ - @Override - public boolean isStatic() { - return isStatic; - } - - - public void setParent(CodeBlock parent) { - this.parent = parent; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/CompilationUnit.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/CompilationUnit.java deleted file mode 100644 index 0aef9e7f..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/CompilationUnit.java +++ /dev/null @@ -1,290 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.rjc.ast; - -import java.awt.Point; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.fife.rsta.ac.bsh.rjc.lang.Annotation; -import org.fife.rsta.ac.bsh.rjc.lexer.Offset; -import org.fife.rsta.ac.bsh.rjc.lexer.Token; -import org.fife.rsta.ac.bsh.rjc.notices.ParserNotice; - - -/** - * A CompilationUnit is the root node of an AST for a Java - * source file. - * - *

    - * CompilationUnit:
    - *    [[Annotations] 'package' QualifiedIdentifier ';' ] {ImportDeclaration} {TypeDeclaration}
    - * 
    - * - * @author Robert Futrell - * @version 1.0 - */ -public class CompilationUnit extends AbstractASTNode - implements TypeDeclarationContainer { - - private List annotations; - private Package pkg; - private List imports; - private List typeDeclarations; - private List notices; - - private static final Offset ZERO_OFFSET = new ZeroOffset(); - - - public CompilationUnit(String name) { - super(name, ZERO_OFFSET); - imports = new ArrayList(3); // Usually not many, - typeDeclarations = new ArrayList(1); // Usually only 1 - } - - - public void addImportDeclaration(ImportDeclaration dec) { - imports.add(dec); - } - - - /** - * Shorthand for "addParserNotice(new ParserNotice(t, msg))". - * - * @param t - * @param msg - */ - public void addParserNotice(Token t, String msg) { - addParserNotice(new ParserNotice(t, msg)); - } - - - public void addParserNotice(ParserNotice notice) { - if (notices==null) { - notices = new ArrayList(); - notices.add(notice); - } - } - - - public void addTypeDeclaration(TypeDeclaration typeDec) { - typeDeclarations.add(typeDec); - } - - - public int getAnnotationCount() { - return annotations.size(); - } - - - public Iterator getAnnotationIterator() { - return annotations.iterator(); - } - - - /** - * Returns the deepest-nested type declaration that contains a given - * offset. - * - * @param offs The offset. - * @return The deepest-nested type declaration containing the offset, or - * null if the offset is outside of any type - * declaration (such as in the import statements, etc.). - * @see #getTypeDeclarationAtOffset(int) - */ - public TypeDeclaration getDeepestTypeDeclarationAtOffset(int offs) { - - TypeDeclaration td = getTypeDeclarationAtOffset(offs); - - if (td!=null) { - TypeDeclaration next = td.getChildTypeAtOffset(offs); - while (next!=null) { - td = next; - next = td.getChildTypeAtOffset(offs); - } - } - - return td; - - } - - - /** - * TODO: Return range for more instances than just class methods. - * Also handle child TypeDeclarations. - * - * @param offs - * @return The starting and ending offset of the enclosing method range. - */ - public Point getEnclosingMethodRange(int offs) { - - Point range = null; - - for (Iterator i=getTypeDeclarationIterator(); i.hasNext(); ) { - - TypeDeclaration td = i.next(); - int start = td.getBodyStartOffset(); - int end = td.getBodyEndOffset(); - - if (offs>=start && offs<=end) { - - if (td instanceof NormalClassDeclaration) { - NormalClassDeclaration ncd = (NormalClassDeclaration)td; - for (Iterator j=ncd.getMemberIterator(); j.hasNext(); ) { - Member m = j.next(); - if (m instanceof Method) { - Method method = (Method)m; - CodeBlock body = method.getBody(); - if (body!=null) { - int start2 = method.getNameStartOffset(); - //int start2 = body.getStartOffset(); - int end2 = body.getNameEndOffset(); - if (offs>=start2 && offs<=end2) { - range = new Point(start2, end2); - break; - } - } - } - } - } - - if (range==null) { // Default to the entire class' body. - range = new Point(start, end); - } - - } - - } - - return range; - - } - - - public int getImportCount() { - return imports.size(); - } - - - /** - * Returns the import declarations of this compilation unit. This is a - * copy of the list of imports, but the actual individual - * {@link ImportDeclaration}s are not copies, so modifying them will modify - * this compilation unit! - * - * @return A list or imports, or an empty list if there are none. - */ - public List getImports() { - return new ArrayList(imports); - } - - - public Iterator getImportIterator() { - return imports.iterator(); - } - - - /** - * Returns the package of this compilation unit. - * - * @return The package of this compilation unit, or null if - * this compilation unit is not in a package. - * @see #getPackageName() - */ - public Package getPackage() { - return pkg; - } - - - /** - * Returns the fully-qualified package name of this compilation unit. - * - * @return The package name, or null if this compilation unit - * is not in a package (in the default package). - * @see #getPackage() - */ - public String getPackageName() { - return pkg==null ? null : pkg.getName(); - } - - - public ParserNotice getParserNotice(int index) { - if (notices==null) { - throw new IndexOutOfBoundsException("No parser notices available"); - } - return notices.get(index); - } - - - public int getParserNoticeCount() { - return notices==null ? 0 : notices.size(); - } - - - public TypeDeclaration getTypeDeclaration(int index) { - return typeDeclarations.get(index); - } - - - /** - * Returns the type declaration in this file that contains the specified - * offset. - * - * @param offs The offset. - * @return The type declaration, or null if the offset is - * outside of any type declaration. - * @see #getDeepestTypeDeclarationAtOffset(int) - */ - public TypeDeclaration getTypeDeclarationAtOffset(int offs) { - - TypeDeclaration typeDec = null; - - for (TypeDeclaration td : typeDeclarations) { - if (td.getBodyContainsOffset(offs)) { - typeDec = td; - break; - } - } - - return typeDec; - - } - - - public int getTypeDeclarationCount() { - return typeDeclarations.size(); - } - - - public Iterator getTypeDeclarationIterator() { - return typeDeclarations.iterator(); - } - - - public void setPackage(Package pkg) { - this.pkg = pkg; - } - - - /** - * An offset that always returns 0. - */ - private static class ZeroOffset implements Offset { - - public int getOffset() { - return 0; - } - - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/EnumBody.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/EnumBody.java deleted file mode 100644 index db559d83..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/EnumBody.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.rjc.ast; - -import org.fife.rsta.ac.bsh.rjc.lexer.Offset; - - -/** - * An EnumBody. - * - *
    - * EnumBody:
    - *    '{' [EnumConstants] [,] [EnumBodyDeclarations] '}'
    - *
    - *
    - * EnumConstants:
    - *    EnumConstant
    - *    EnumConstants , EnumConstant
    - *
    - * EnumConstant:
    - *    Annotations Identifier [Arguments] [ClassBody]
    - *
    - * EnumBodyDeclarations:
    - *    ; {ClassBodyDeclaration}
    - * 
    - * - * @author Robert Futrell - * @version 1.0 - */ -public class EnumBody extends AbstractASTNode { - - - public EnumBody(String name, Offset start) { - super(name, start); - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/EnumDeclaration.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/EnumDeclaration.java deleted file mode 100644 index 07416122..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/EnumDeclaration.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.rjc.ast; - -import org.fife.rsta.ac.bsh.rjc.lexer.Scanner; - - -public class EnumDeclaration extends AbstractTypeDeclarationNode { - -// private EnumBody enumBody; - - - public EnumDeclaration(Scanner s, int offs, String name) { - super(name, s.createOffset(offs), s.createOffset(offs+name.length())); - } - - - public String getTypeString() { - return "enum"; - } - - -// public void setEnumBody(EnumBody enumBody) { -// this.enumBody = enumBody; -// } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/Field.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/Field.java deleted file mode 100644 index 21b42b95..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/Field.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.rjc.ast; - -import org.fife.rsta.ac.bsh.rjc.lang.Modifiers; -import org.fife.rsta.ac.bsh.rjc.lang.Type; -import org.fife.rsta.ac.bsh.rjc.lexer.Scanner; -import org.fife.rsta.ac.bsh.rjc.lexer.Token; - - -public class Field extends AbstractMember { - - private Modifiers modifiers; - private Type type; - private boolean deprecated; - private String docComment; - - - public Field(Scanner s, Modifiers modifiers, Type type, Token t) { - super(t.getLexeme(), s.createOffset(t.getOffset())); - setDeclarationEndOffset(s.createOffset(t.getOffset() + t.getLength())); - if (modifiers==null) { - modifiers = new Modifiers(); - } - this.modifiers = modifiers; - this.type = type; - } - - - public String getDocComment() { - return docComment; - } - - - public Modifiers getModifiers() { - return modifiers; - } - - - public Type getType() { - return type; - } - - - public boolean isDeprecated() { - return deprecated; - } - - - public void setDeprecated(boolean deprecated) { - this.deprecated = deprecated; - } - - - public void setDocComment(String comment) { - docComment = comment; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/FormalParameter.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/FormalParameter.java deleted file mode 100644 index c927cf66..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/FormalParameter.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.rjc.ast; - -import java.util.List; - -import org.fife.rsta.ac.bsh.rjc.lang.Annotation; -import org.fife.rsta.ac.bsh.rjc.lang.Type; -import org.fife.rsta.ac.bsh.rjc.lexer.Scanner; - - -/** - * A parameter to a method. - * - * @author Robert Futrell - * @version 1.0 - */ -/* - * FormalParameter: - * ['final'] [Annotations] Type VariableDeclaratorId - * - * VariableDeclaratorId: - * Identifier { "[" "]" } - */ -public class FormalParameter extends LocalVariable { - - private List annotations; - - - public FormalParameter(Scanner s, boolean isFinal, - Type type, int offs, String name, List annotations) { - super(s, isFinal, type, offs, name); - this.annotations = annotations; - } - - - public int getAnnotationCount() { - return annotations==null ? 0 : annotations.size(); - } - - - /** - * Overridden to return "getType() getName()". - * - * @return This parameter, as a string. - */ - @Override - public String toString() { - return getType() + " " + getName(); - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/ImportDeclaration.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/ImportDeclaration.java deleted file mode 100644 index 865a5fbf..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/ImportDeclaration.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.rjc.ast; - -import org.fife.rsta.ac.bsh.rjc.lexer.Scanner; - - -/** - * An import declaration in a class file. - * - * @author Robert Futrell - * @version 1.0 - */ -public class ImportDeclaration extends AbstractASTNode { - - private boolean isStatic; - - - public ImportDeclaration(Scanner s, int offs, String info, boolean isStatic) { - super(info, s.createOffset(offs), s.createOffset(offs+info.length())); - setStatic(isStatic); - } - - - public boolean isStatic() { - return isStatic; - } - - - public boolean isWildcard() { - return getName().endsWith(".*"); - } - - - public void setStatic(boolean isStatic) { - this.isStatic = isStatic; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/LocalVariable.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/LocalVariable.java deleted file mode 100644 index ddf7946d..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/LocalVariable.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.rjc.ast; - -import org.fife.rsta.ac.bsh.rjc.lang.Type; -import org.fife.rsta.ac.bsh.rjc.lexer.Scanner; - - -/** - * Base class for local variables and formal parameters. - * - * @author Robert Futrell - * @version 1.0 - */ -public class LocalVariable extends AbstractASTNode { - - private boolean isFinal; - private Type type; - - - public LocalVariable(Scanner s, boolean isFinal, - Type type, int offs, String name) { - super(name, s.createOffset(offs), s.createOffset(offs+name.length())); - this.isFinal = isFinal; - this.type = type; - } - - - public Type getType() { - return type; - } - - - public boolean isFinal() { - return isFinal; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/Member.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/Member.java deleted file mode 100644 index 6eb38d25..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/Member.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.rjc.ast; - -import org.fife.rsta.ac.bsh.rjc.lang.Modifiers; -import org.fife.rsta.ac.bsh.rjc.lang.Type; - - -/** - * A marker for a member of a class or interface. - * - * @author Robert Futrell - * @version 1.0 - */ -public interface Member extends ASTNode { - - - public String getDocComment(); - - - public int getNameEndOffset(); - - - public int getNameStartOffset(); - - - public Modifiers getModifiers(); - - - public String getName(); - - - public TypeDeclaration getParentTypeDeclaration(); - - - public Type getType(); - - - public boolean isDeprecated(); - - - /** - * Shortcut for getModifiers().isStatic(); useful since - * getModifiers() may return null. - * - * @return Whether this member is static. - * @see #getModifiers() - */ - public boolean isStatic(); - - - public void setParentTypeDeclaration(TypeDeclaration dec); - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/Method.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/Method.java deleted file mode 100644 index fbdbe134..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/Method.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.rjc.ast; - -import java.util.Iterator; -import java.util.List; - -import org.fife.rsta.ac.bsh.rjc.lang.Modifiers; -import org.fife.rsta.ac.bsh.rjc.lang.Type; -import org.fife.rsta.ac.bsh.rjc.lexer.Scanner; -import org.fife.rsta.ac.bsh.rjc.lexer.Token; - - -// TODO: Implement me correctly -public class Method extends AbstractMember { - - private Modifiers modifiers; - private Type type; - private List parameters; - private List thrownTypeNames; - private CodeBlock body; - private boolean deprecated; - private String docComment; - - - public Method(Scanner s, Modifiers modifiers, Type type, Token nameToken, - List params, List thrownTypeNames) { - super(nameToken.getLexeme(), - s.createOffset(nameToken.getOffset()), - s.createOffset(nameToken.getOffset() + nameToken.getLength())); - if (modifiers==null) { - modifiers = new Modifiers(); - } - this.modifiers = modifiers; - this.type = type; - this.parameters = params; - this.thrownTypeNames = thrownTypeNames; - } - - - public CodeBlock getBody() { - return body; - } - - - public boolean getBodyContainsOffset(int offs) { - return offs>=getBodyStartOffset() && offs getParameterIterator() { - return parameters.iterator(); - } - - - public int getThrownTypeNameCount() { - return thrownTypeNames==null ? 0 : thrownTypeNames.size(); - } - - - public Type getType() { - return type; - } - - - public boolean isConstructor() { - return type==null; - } - - - public boolean isDeprecated() { - return deprecated; - } - - - public void setBody(CodeBlock body) { - this.body = body; - } - - - public void setDeprecated(boolean deprecated) { - this.deprecated = deprecated; - } - - - public void setDocComment(String comment) { - docComment = comment; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/NormalClassDeclaration.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/NormalClassDeclaration.java deleted file mode 100644 index 3bb217f5..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/NormalClassDeclaration.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.rjc.ast; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.fife.rsta.ac.bsh.rjc.lang.Type; -import org.fife.rsta.ac.bsh.rjc.lang.TypeParameter; -import org.fife.rsta.ac.bsh.rjc.lexer.Scanner; - - -/** - * A class declaration: - * - *
    - * NormalClassDeclaration:
    - *    'class' Identifier [TypeParameters] ['extends' Type] ['implements' TypeList] ClassBody
    - * 
    - * - * @author Robert Futrell - * @version 1.0 - */ -public class NormalClassDeclaration extends AbstractTypeDeclarationNode { - - // --- "NormalClassDeclaration" fields --- - private List typeParams; - private Type extendedType; - private List implementedList; - - - public NormalClassDeclaration(Scanner s, int offs, String className) { - super(className, s.createOffset(offs), s.createOffset(offs+className.length())); - implementedList = new ArrayList(0); // Usually not many - // If parsing java.lang.Object.java, setExtendedType(null) should be - // called. This is here for all other classes without an explicit - // super class declared. - extendedType = new Type("java.lang.Object"); - } - - - public void addImplemented(Type implemented) { - implementedList.add(implemented); - } - - - public Type getExtendedType() { - return extendedType; - } - - - public int getImplementedCount() { - return implementedList.size(); - } - - - public Iterator getImplementedIterator() { - return implementedList.iterator(); - } - - - /** - * Gets the method in this class that contains a given offset. - * - * @param offs The offset. - * @return The method containing the offset, or null if no - * method in this class contains the offset. - */ - public Method getMethodContainingOffset(int offs) { - for (Iterator i=getMethodIterator(); i.hasNext(); ) { - Method method = i.next(); - if (method.getBodyContainsOffset(offs)) { - return method; - } - } - return null; - } - - - public List getTypeParameters() { - return typeParams; - } - - - public String getTypeString() { - return "class"; - } - - - /** - * Returns whether a Type and a type name are type - * compatible. This method currently is a sham! - * - * @param type - * @param typeName - * @return - */ - // TODO: Get me working! Probably need better parameters passed in!!! - private boolean isTypeCompatible(Type type, String typeName) { - - String typeName2 = type.getName(false); - - // Remove generics info for now - // TODO: Handle messy generics cases - int lt = typeName2.indexOf('<'); - if (lt>-1) { - String arrayDepth = null; - int brackets = typeName2.indexOf('[', lt); - if (brackets>-1) { - arrayDepth = typeName2.substring(brackets); - } - typeName2 = typeName2.substring(lt); - if (arrayDepth!=null) { - typeName2 += arrayDepth; - } - } - - return typeName2.equalsIgnoreCase(typeName); - - } - - - public void setExtendedType(Type type) { - extendedType = type; - } - - - public void setTypeParameters(List typeParams) { - this.typeParams = typeParams; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/NormalInterfaceDeclaration.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/NormalInterfaceDeclaration.java deleted file mode 100644 index 49b47e23..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/NormalInterfaceDeclaration.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.rjc.ast; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import org.fife.rsta.ac.bsh.rjc.lang.Type; -import org.fife.rsta.ac.bsh.rjc.lexer.Scanner; - - -/** - * An interface declaration: - * - *
    - * NormalInterfaceDeclaration:
    - *    'interface' Identifier [TypeParameters] ['extends' TypeList] InterfaceBody
    - * 
    - * - * @author Robert Futrell - * @version 1.0 - */ -public class NormalInterfaceDeclaration extends AbstractTypeDeclarationNode { - - private List extendedList; - - - public NormalInterfaceDeclaration(Scanner s, int offs, String name) { - super(name, s.createOffset(offs), s.createOffset(offs+name.length())); - extendedList = new ArrayList(1); // Usually small - } - - - public void addExtended(Type extended) { - extendedList.add(extended); - } - - - public int getExtendedCount() { - return extendedList.size(); - } - - - public Iterator getExtendedIterator() { - return extendedList.iterator(); - } - - - public String getTypeString() { - return "interface"; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/Package.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/Package.java deleted file mode 100644 index 2dba37be..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/Package.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.rjc.ast; - -import org.fife.rsta.ac.bsh.rjc.lexer.Scanner; - - -public class Package extends AbstractASTNode { - - - public Package(Scanner s, int offs, String pkg) { - super(pkg, s.createOffset(offs), s.createOffset(offs+pkg.length())); - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/TypeDeclaration.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/TypeDeclaration.java deleted file mode 100644 index 05b7a912..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/TypeDeclaration.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.rjc.ast; - -import java.util.Iterator; -import java.util.List; - -import org.fife.rsta.ac.bsh.rjc.lang.Modifiers; - - -public interface TypeDeclaration extends ASTNode, TypeDeclarationContainer { - - - public boolean getBodyContainsOffset(int offs); - - - public int getBodyEndOffset(); - - - public int getBodyStartOffset(); - - - public TypeDeclaration getChildType(int index); - - - /** - * Returns the child type declaration of this one that contains the - * specified offset, if any. - * - * @param offs The offset. - * @return The type declaration, or null if the offset is - * outside of any child type declaration. - */ - public TypeDeclaration getChildTypeAtOffset(int offs); - - - public int getChildTypeCount(); - - - public String getDocComment(); - - - /** - * Returns an iterator over all fields defined in this type. - * - * @return The iterator. - * @see #getMethodIterator() - * @see #getMemberIterator() - */ - public Iterator getFieldIterator(); - - - public Member getMember(int index); - - - public int getMemberCount(); - - - /** - * Returns an iterator over all members of this type. Note - * that an exception may be thrown if a method is added to this type - * while this iterator is being used. - * - * @return The iterator. - * @see #getMethodIterator() - */ - public Iterator getMemberIterator(); - - - /** - * Returns an iterator over all methods defined in this type. - * - * @return The iterator. - * @see #getFieldIterator() - * @see #getMemberIterator() - */ - public Iterator getMethodIterator(); - - - /** - * Returns all methods declared in this type with the given name. Does - * not check for methods with this name in subclasses. - * - * @param name The name to check for. - * @return Any method overloads with that name, or an empty list if none. - */ - public List getMethodsByName(String name); - - - /** - * Returns the modifiers of this type declaration. - * - * @return The modifier list. This may be null if no - * modifiers were specified. - */ - public Modifiers getModifiers(); - - - /** - * Returns the name of this type, unqualified. - * - * @return The name of this type. - * @see #getName(boolean) - */ - public String getName(); - - - /** - * Returns the name of this type. - * - * @param fullyQualified Whether the name returned should be fully - * qualified. - * @return The type's name. - * @see #getName() - */ - public String getName(boolean fullyQualified); - - - /** - * Returns the package this type is in. - * - * @return The package, or null if it's in the default package. - */ - public Package getPackage(); - - - /** - * Returns the parent type declaration. - * - * @return The parent type declaration, or null if there isn't - * one. - * @see #setParentType(TypeDeclaration) - */ - public TypeDeclaration getParentType(); - - - public String getTypeString(); - - - public boolean isDeprecated(); - - - /** - * Shortcut for getModifiers().isStatic(); useful since - * getModifiers() may return null. - * - * @return Whether this type declaration is static. - * @see #getModifiers() - */ - public boolean isStatic(); - - - public void setDocComment(String comment); - - - /** - * Sets the parent type declaration for this type declaration. - * - * @param parentType The parent type declaration. - * @see #getParentType() - */ - public void setParentType(TypeDeclaration parentType); - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/TypeDeclarationContainer.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/TypeDeclarationContainer.java deleted file mode 100644 index c76c4087..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/rjc/ast/TypeDeclarationContainer.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.rjc.ast; - - -/** - * Interface for tree nodes that can hold type declarations (e.g. - * {@link CompilationUnit}s and {@link TypeDeclaration}s. - * - * @author Robert Futrell - * @version 1.0 - */ -public interface TypeDeclarationContainer { - - - public void addTypeDeclaration(TypeDeclaration typeDec); - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/lang/Annotation.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/lang/Annotation.java deleted file mode 100644 index 88db6ddb..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/rjc/lang/Annotation.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.rjc.lang; - - -public class Annotation { - - private Type type; - - - public Annotation(Type type) { - this.type = type; - } - - - @Override - public String toString() { - return "@" + type.toString(); - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/lang/Modifiers.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/lang/Modifiers.java deleted file mode 100644 index 5ca4eed5..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/rjc/lang/Modifiers.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.rjc.lang; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.fife.rsta.ac.bsh.rjc.lexer.TokenTypes; - - -/** - * Wrapper around modifiers to a member. - * - * @author Robert Futrell - * @version 1.0 - */ -public class Modifiers { - - public static final Integer ABSTRACT = new Integer(1024); - public static final Integer FINAL = new Integer(16); - public static final Integer INTERFACE = new Integer(512); - public static final Integer NATIVE = new Integer(256); - public static final Integer PRIVATE = new Integer(2); - public static final Integer PROTECTED = new Integer(4); - public static final Integer PUBLIC = new Integer(1); - public static final Integer STATIC = new Integer(8); - public static final Integer STRICTFP = new Integer(2048); - public static final Integer SYNCHRONIZED = new Integer(32); - public static final Integer TRANSIENT = new Integer(128); - public static final Integer VOLATILE = new Integer(64); - - private List modifiers; - private List annotations; - - - private static final Map MODIFIER_TEXT - = new HashMap() { - - private static final long serialVersionUID = 1L; - - { - put(ABSTRACT, "abstract"); - put(FINAL, "final"); - put(INTERFACE, "interface"); - put(NATIVE, "native"); - put(PRIVATE, "private"); - put(PROTECTED, "protected"); - put(PUBLIC, "public"); - put(STATIC, "static"); - put(STRICTFP, "strictfp"); - put(SYNCHRONIZED, "synchronized"); - put(TRANSIENT, "transient"); - put(VOLATILE, "volatile"); - } - }; - - - public Modifiers() { - modifiers = new ArrayList(1); // Usually not many. - annotations = new ArrayList(0); // Often 0 or 1 (@Deprecated) - } - - - public void addAnnotation(Annotation annotation) { - annotations.add(annotation); - } - - - public boolean addModifier(int tokenType) { - - Integer key = null; - - switch (tokenType) { - case TokenTypes.KEYWORD_ABSTRACT: - key = ABSTRACT; - break; - case TokenTypes.KEYWORD_FINAL: - key = FINAL; - break; - case TokenTypes.KEYWORD_INTERFACE: - key = INTERFACE; - break; - case TokenTypes.KEYWORD_NATIVE: - key = NATIVE; - break; - case TokenTypes.KEYWORD_PRIVATE: - key = PRIVATE; - break; - case TokenTypes.KEYWORD_PROTECTED: - key = PROTECTED; - break; - case TokenTypes.KEYWORD_PUBLIC: - key = PUBLIC; - break; - case TokenTypes.KEYWORD_STATIC: - key = STATIC; - break; - case TokenTypes.KEYWORD_STRICTFP: - key = STRICTFP; - break; - case TokenTypes.KEYWORD_SYNCHRONIZED: - key = SYNCHRONIZED; - break; - case TokenTypes.KEYWORD_TRANSIENT: - key = TRANSIENT; - break; - case TokenTypes.KEYWORD_VOLATILE: - key = VOLATILE; - break; - default: - throw new IllegalArgumentException("Invalid tokenType: " + - tokenType); - } - - int pos = Collections.binarySearch(modifiers, key); - if (pos<0) { - // pos = -insertionPoint - 1 - int insertionPoint = -(pos+1); - modifiers.add(insertionPoint, key); - } - - return pos<0; - - } - - - private boolean containsModifier(Integer modifierKey) { - return Collections.binarySearch(modifiers, modifierKey)>=0; - } - - - public boolean isAbstract() { - return containsModifier(ABSTRACT); - } - - - public boolean isFinal() { - return containsModifier(FINAL); - } - - - public boolean isPrivate() { - return containsModifier(PRIVATE); - } - - - public boolean isProtected() { - return containsModifier(PROTECTED); - } - - - public boolean isPublic() { - return containsModifier(PUBLIC); - } - - - public boolean isStatic() { - return containsModifier(STATIC); - } - - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - for (int i=0; i0) { - sb.append(' '); - } - } - for (int i=0; i - * Type: - * Identifier [TypeArguments] { . Identifier [TypeArguments] } {[]} - * BasicType - * - * - * @author Robert Futrell - * @version 1.0 - */ -public class Type { - - private List identifiers; - private List> typeArguments; - private int bracketPairCount; - - - public Type() { - identifiers = new ArrayList(1); - typeArguments = new ArrayList>(1); - } - - - public Type(String identifier) { - this(); - addIdentifier(identifier, null); - } - - - public Type(String identifier, int bracketPairCount) { - this(); - addIdentifier(identifier, null); - setBracketPairCount(bracketPairCount); - } - - - /** - * Adds an identifier to this type. - * - * @param identifier The identifier. - * @param typeArgs The type arguments for the identifier. This may be - * null or an empty list if there are none. - */ - public void addIdentifier(String identifier, List typeArgs) { - identifiers.add(identifier); - typeArguments.add(typeArgs); - } - - - public int getIdentifierCount() { - return identifiers.size(); - } - - - /** - * Returns the name of this type. - * - * @param fullyQualified Whether the returned value should be - * fully qualified. - * @return The name of this type. This will include type arguments, - * if any. - * @see #getName(boolean, boolean) - */ - public String getName(boolean fullyQualified) { - return getName(fullyQualified, true); - } - - - /** - * Returns the name of this type. - * - * @param fullyQualified Whether the returned value should be - * fully qualified. - * @param addTypeArgs Whether type arguments should be at the end of - * the returned string, if any. - * @return The name of this type. - * @see #getName(boolean) - */ - public String getName(boolean fullyQualified, boolean addTypeArgs) { - - StringBuilder sb = new StringBuilder(); - - int count = identifiers.size(); - int start = fullyQualified ? 0 : count-1; - for (int i=start; i typeArgs = typeArguments.get(i); - int typeArgCount = typeArgs.size(); - if (typeArgCount>0) { - sb.append('<'); - for (int j=0; j'); - } - } - if (i getTypeArguments(int index) { - return typeArguments.get(index); - } - - - /* - * MethodDeclaratorRest allows bracket pairs after its FormalParameters, - * which increment the array depth of the return type. - */ - public void incrementBracketPairCount(int count) { - bracketPairCount += count; - } - - - /** - * Returns whether this type is an array. - * - * @return Whether this type is an array. - */ - public boolean isArray() { - return bracketPairCount>0; - } - - - public boolean isBasicType() { - boolean basicType = false; - if (!isArray() && identifiers.size()==1 && typeArguments.get(0)==null) { - String str = identifiers.get(0); - basicType = "byte".equals(str) || - "float".equals(str) || - "double".equals(str) || - "int".equals(str) || - "short".equals(str) || - "long".equals(str) || - "boolean".equals(str); - } - return basicType; - } - - - public void setBracketPairCount(int count) { - bracketPairCount = count; - } - - - /** - * Returns a string representation of this type. The type name will be - * fully qualified. - * - * @return A string representation of this type. - * @see #getName(boolean) - */ - @Override - public String toString() { - return getName(true); - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/lang/TypeArgument.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/lang/TypeArgument.java deleted file mode 100644 index 9ec73636..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/rjc/lang/TypeArgument.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.rjc.lang; - - -public class TypeArgument { - - public static final int NOTHING = 0; - public static final int EXTENDS = 1; - public static final int SUPER = 2; - - private Type type; - private int doesExtend; - private Type otherType; - - - public TypeArgument(Type type) { - this.type = type; - } - - - public TypeArgument(Type type, int doesExtend, Type otherType) { - if (doesExtend<0 || doesExtend>2) { - throw new IllegalArgumentException("Illegal doesExtend: " + doesExtend); - } - this.type = type; - this.doesExtend = doesExtend; - this.otherType = otherType; - } - - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - if (type==null) { - sb.append('?'); - } - else { - sb.append(type.toString()); - } - if (doesExtend==EXTENDS) { - sb.append(" extends "); - sb.append(otherType.toString()); - } - else if (doesExtend==SUPER) { - sb.append(" super "); - sb.append(otherType.toString()); - } - return sb.toString(); - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/lang/TypeParameter.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/lang/TypeParameter.java deleted file mode 100644 index 3741a054..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/rjc/lang/TypeParameter.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.rjc.lang; - -import java.util.ArrayList; -import java.util.List; - -import org.fife.rsta.ac.bsh.rjc.lexer.Token; - - -/** - * A TypeParameter. - * - *
    - * TypeParameter:
    - *    Identifier ['extends' Bound]
    - * 
    - * Bound:
    - *    Type { '&' Type }
    - * 
    - * - * @author Robert Futrell - * @version 1.0 - */ -public class TypeParameter { - - private Token name; - private List bounds; - - - public TypeParameter(Token name) { - this.name = name; - } - - - public void addBound(Type bound) { - if (bounds==null) { - bounds = new ArrayList(1); // Usually just 1 - } - bounds.add(bound); - } - - - public String getName() { - return name.getLexeme(); - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/lang/Variable.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/lang/Variable.java deleted file mode 100644 index 32920a14..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/rjc/lang/Variable.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.rjc.lang; - -import org.fife.rsta.ac.bsh.rjc.lexer.Token; - - -/** - * Base class for variable type (local variables, formal parameters...). - * - * @author Robert Futrell - * @version 1.0 - */ -public abstract class Variable { - - private boolean isFinal; - private Type type; - private Token name; - - - public Variable(boolean isFinal, Type type, Token name) { - this.isFinal = isFinal; - this.type = type; - this.name = name; - } - - - public String getName() { - return name.getLexeme(); - } - - - public Type getType() { - return type; - } - - - public boolean isFinal() { - return isFinal; - } - - -} diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/Offset.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/Offset.java deleted file mode 100644 index 6b4e981a..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/Offset.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.rjc.lexer; - - -/** - * An offset into Java source. This is an interface so we can wrap - * javax.swing.text.Position instances when parsing code in a - * JTextComponent, so these offsets can get tracked. - * - * @author Robert Futrell - * @version 1.0 - */ -public interface Offset { - - - /** - * Returns the offset into the source. - * - * @return The offset. - */ - public int getOffset(); - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/Scanner.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/Scanner.java deleted file mode 100644 index 4c0d4c87..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/Scanner.java +++ /dev/null @@ -1,870 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.rjc.lexer; - -import java.io.EOFException; -import java.io.IOException; -import java.io.Reader; -import java.util.List; -import java.util.Stack; -import javax.swing.text.BadLocationException; -import javax.swing.text.Document; -import javax.swing.text.Position; - - -/** - * A scanner that allows the user to "push back" tokens. This scanner - * allows arbitrary lookahead. - * - * @author Robert Futrell - * @version 1.0 - */ -public class Scanner { - - private static final boolean DEBUG = false; - - /** - * The scanner we delegate to. - */ - private SourceCodeScanner s; - - /** - * Stack of tokens that have been "pushed back." - */ - private Stack stack; - - /** - * The depth in which we're in TypeArguments or TypeParameters. - */ - private int typeArgLevel; - - /** - * If we are parsing text in a Swing JTextComponent, this - * should be the document of that component. - */ - private Document doc; - - /** - * The most recently lexed token, or null if EOS was - * reached. - */ - private Token mostRecentToken; - - - /** - * Constructor. This scanner will return no tokens unless some are pushed - * onto it via {@link #yyPushback(Token)}. - */ - public Scanner() { - this((Reader)null); - } - - - /** - * Constructor. This scanner will only return those tokens pushed onto it. - * - * @param tokens Tokens to return. - */ - public Scanner(List tokens) { - stack = new Stack(); - for (int i=tokens.size()-1; i>=0; i--) { - stack.push(tokens.get(i)); - } - } - - - /** - * Constructor. - * - * @param r The stream to read from. - */ - public Scanner(Reader r) { - s = r!=null ? new SourceCodeScanner(r) : null; - s.setKeepLastDocComment(true); - stack = new Stack(); - } - - -/** - * This method is just here for debugging purposes to make sure - * our parser is sound. - * - * @param t A token to push onto the stack (non-null). - */ -private void pushOntoStack(Token t) { - if (t!=null && !stack.isEmpty() && t.equals(stack.peek())) { - System.err.println("ERROR: Token being duplicated: " + t); - Thread.dumpStack(); - System.exit(5); - } - else if (t==null) { - System.err.println("ERROR: null token pushed onto stack"); - Thread.dumpStack(); - System.exit(6); - } - stack.push(t); -} - - - /** - * Decreases the depth in which we're in TypeArguments or TypeParameters. - * - * @see #increaseTypeArgumentsLevel() - * @see #getTypeArgumentsLevel() - */ - public void decreaseTypeArgumentsLevel() { - if (--typeArgLevel<0) { - throw new InternalError("typeArgLevel dipped below 0"); - } - } - - - /** - * Returns an offset into the source being parsed. This offset will be - * tracked if we are parsing code from a Swing JTextComponent. - * - * @param offs The offset. - * @return An object representing the offset. - * @see #setDocument(Document) - */ - public Offset createOffset(final int offs) { - if (doc!=null) { - try { - return new DocumentOffset(doc.createPosition(offs)); - } catch (BadLocationException ble) { // Should never happen - ble.printStackTrace(); - } - } - return new Offset() { - public int getOffset() { - return offs; - } - }; - } - - - private void debugPrintToken(Token t) { - if (DEBUG) { - if (t==null) { - System.out.println("... null"); - } - else { - System.out.println("... " + t); - } - } - } - - - /** - * Returns the current column into the current line. - * - * @return The current column. - * @see #getLine() - */ - public int getColumn() { - return s.getColumn(); - } - - - /** - * Returns the last documentation comment parsed. The "last documentation - * comment" is cleared when this method returns. - * - * @return The last documentation comment parsed, or null - * if there was none. - */ - public String getLastDocComment() { - return s.getLastDocComment(); - } - - - /** - * Returns the current line into the document. - * - * @return The current line. - * @see #getColumn() - */ - public int getLine() { - return s.getLine(); - } - - - /** - * Returns the most recently-lexed token. - * - * @return The token, or null if EOS was reached. - */ - public Token getMostRecentToken() { - return mostRecentToken; - } - - - /** - * Returns the current offset into the document. - * - * @return The offset. - */ - public int getOffset() { - return s.getOffset(); - } - - - /** - * Eats through (possibly nested) paren pairs, e.g.: - *
    (int i=0; i<getFoo(getParam()); i++)
    . - * Blocks nested inside the paren pairs are also skipped. - * - * @throws IOException If an IO error occurs. - * @throws InternalError If the next token is not a '('. - */ - public void eatParenPairs() throws IOException { - - Token t = yylex(); - if (t==null || t.getType()!=TokenTypes.SEPARATOR_LPAREN) { - throw new InternalError("'(' expected, found: " + t); - } - - int blockDepth = 0; - int parenDepth = 1; - - while ((t=yylex())!=null) { - int type = t.getType(); - switch (type) { - case TokenTypes.SEPARATOR_LBRACE: - blockDepth++; - break; - case TokenTypes.SEPARATOR_RBRACE: - blockDepth = Math.max(blockDepth-1, 0); - break; - case TokenTypes.SEPARATOR_LPAREN: - if (blockDepth==0) { - parenDepth++; - } - break; - case TokenTypes.SEPARATOR_RPAREN: - if (blockDepth==0 && --parenDepth == 0) { - return; - } - break; - } - } - - } - - - /** - * Eats all tokens up to (and including) the next token of the specified - * type. This is useful, for example, to eat until the next semicolon. - * - * @param tokenType The type of token to eat through. - * @throws IOException If an IO error occurs. - */ - public void eatThroughNext(int tokenType) throws IOException { - Token t = null; - while ((t=yylex())!=null && t.getType()!=tokenType); - } - - - /** - * Eats all tokens up to (and including) the next token of the specified - * type. This is useful, for example, to eat until the next semicolon. - * - * @param tokenType The type of token to eat through. - * @throws IOException If an IO error occurs. - * @see #eatThroughNextSkippingBlocks(int, int) - * @see #eatThroughNextSkippingBlocksAndStuffInParens(int, int) - */ - public void eatThroughNextSkippingBlocks(int tokenType) throws IOException { - Token t = null; - int blockDepth = 0; - while ((t=yylex())!=null) { - int type = t.getType(); - if (type==TokenTypes.SEPARATOR_LBRACE) { - blockDepth++; - } - else if (type==TokenTypes.SEPARATOR_RBRACE) { - blockDepth--; - } - else if (type==tokenType) { - if (blockDepth<=0) { - return; - } - } - } - } - - - /** - * Eats all tokens up to (and including) the next token of one of the - * specified types. This is useful, for example, to eat until the next - * equal sign or semicolon. - * - * @param tokenType1 The type of token to eat through. - * @param tokenType2 Another type of token to eat through. - * @return The last token read. This will either be one of the two token - * types passed in, or null if the end of the stream - * is reached. - * @throws IOException If an IO error occurs. - * @see #eatThroughNextSkippingBlocksAndStuffInParens(int, int) - */ - public Token eatThroughNextSkippingBlocks(int tokenType1, - int tokenType2) throws IOException { - Token t = null; - int blockDepth = 0; - while ((t=yylex())!=null) { - int type = t.getType(); - if (type==TokenTypes.SEPARATOR_LBRACE) { - blockDepth++; - } - else if (type==TokenTypes.SEPARATOR_RBRACE) { - blockDepth--; - } - else if (type==tokenType1 || type==tokenType2) { - if (blockDepth<=0) { - return t; - } - } - } - return null; - } - - - /** - * Eats all tokens up to (and including) the next token of one of the - * specified types. This is useful, for example, to eat until the next - * equal sign or semicolon. - * - * @param tokenType1 The type of token to eat through. - * @param tokenType2 Another type of token to eat through. - * @return The last token read. This will either be one of the two token - * types passed in, or null if the end of the stream - * is reached. - * @throws IOException If an IO error occurs. - * @see #eatThroughNextSkippingBlocks(int, int) - */ - public Token eatThroughNextSkippingBlocksAndStuffInParens(int tokenType1, - int tokenType2) throws IOException { - - Token t = null; - int blockDepth = 0; - int parenDepth = 0; - - while ((t=yylex())!=null) { - int type = t.getType(); - switch (type) { - case TokenTypes.SEPARATOR_LBRACE: - blockDepth++; - break; - case TokenTypes.SEPARATOR_RBRACE: - blockDepth--; - break; - case TokenTypes.SEPARATOR_LPAREN: - parenDepth++; - break; - case TokenTypes.SEPARATOR_RPAREN: - parenDepth--; - break; - default: - if (type==tokenType1 || type==tokenType2) { - if (blockDepth<=0 && parenDepth<=0) { - return t; - } - } - } - } - - return null; - - } - - - public void eatUntilNext(int type1, int type2) throws IOException { - Token t = null; - while ((t=yylex())!=null) { - int type = t.getType(); - if (type==type1 || type==type2) { - yyPushback(t); - break; - } - } - } - - - public void eatUntilNext(int type1, int type2, int type3) throws IOException { - Token t = null; - while ((t=yylex())!=null) { - int type = t.getType(); - if (type==type1 || type==type2 || type==type3) { - yyPushback(t); - break; - } - } - } - - - /** - * Returns the current TypeArgument/TypeParameter level. - * - * @return The current level. - * @see #increaseTypeArgumentsLevel() - * @see #decreaseTypeArgumentsLevel() - */ - public int getTypeArgumentsLevel() { - return typeArgLevel; - } - - - /** - * Increases the depth in which we're in TypeArguments or TypeParameters. - * - * @see #decreaseTypeArgumentsLevel() - * @see #getTypeArgumentsLevel() - */ - public void increaseTypeArgumentsLevel() { - typeArgLevel++; - } - - -private Stack> resetPositions; -private Stack currentResetTokenStack; -private int currentResetStartOffset; - public void markResetPosition() { - if (s!=null) { // Hack! We should really do something for token-only scanners - if (resetPositions==null) { - resetPositions = new Stack>(); - } - currentResetTokenStack = new Stack(); - resetPositions.push(currentResetTokenStack); - currentResetStartOffset = s.getOffset(); - } - } - public void resetToLastMarkedPosition() { - if (s!=null) { // Hack! We should really do something for token-only scanners - if (currentResetTokenStack==null) { - throw new InternalError("No resetTokenStack!"); - } - // Remove tokens off the standard stack within the "marked" range - while (!stack.isEmpty()) { - Token t = stack.peek(); - if (t.getOffset()>=currentResetStartOffset) { - stack.pop(); - } - else { - break; - } - } - // Add all tokens in the "marked" range to our stack - while (!currentResetTokenStack.isEmpty()) { - Token t = currentResetTokenStack.pop(); - stack.push(t); - } - resetPositions.pop(); // Remote currentResetTokenStack - currentResetTokenStack = resetPositions.isEmpty() ? null : (Stack)resetPositions.peek(); - currentResetStartOffset = -1; - } - } - public void clearResetPosition() { - if (s!=null) { // Hack! We should really do something for token-only scanners - if (currentResetTokenStack==null) { - throw new InternalError("No resetTokenStack!"); - } - resetPositions.pop(); // Remote currentResetTokenStack - currentResetTokenStack = resetPositions.isEmpty() ? null : (Stack)resetPositions.peek(); - currentResetStartOffset = -1; - } - } - - /** - * Sets the Swing Document whose content is being parsed. - * This method should be called if we are parsing code inside a - * JTextComponent, as it will help our parsed code to track - * changes when the document is modified. If we are parsing source from a - * flat file, this method shouldn't be called. - * - * @param doc The document being parsed. - */ - public void setDocument(Document doc) { - this.doc = doc; - } - - - /** - * Skips all bracket pairs ('[' followed by ']') in the stream. - * - * @return The number of bracket pairs skipped. - * @throws IOException If an IO error occurs. - */ - public int skipBracketPairs() throws IOException { - - int count = 0; - - while (yyPeekCheckType()==TokenTypes.SEPARATOR_LBRACKET && - yyPeekCheckType(2)==TokenTypes.SEPARATOR_RBRACKET) { - yylex(); - yylex(); - count++; - } - - return count; - - } - - - /** - * Returns the next token from the input stream. - * - * @return The next token. - * @throws IOException If an IO error occurs. - */ - /* - * NOTE: All other lex'ing methods should call into this one. - */ - public Token yylex() throws IOException { - - Token t = null; - if (stack.isEmpty()) { - t = s!=null ? s.yylex() : null; - } - else { - t = stack.pop(); - } - - // If we have nested TypeArguments ("Set>"), - // Prevent the ">>" from coming across as a single token. - if (typeArgLevel>0 && t!=null && t.isOperator()) { - String lexeme = t.getLexeme(); - if (lexeme.length()>1) { - char ch = lexeme.charAt(0); - if (ch=='<') { - Token rest = null; - switch (t.getType()) { - case TokenTypes.OPERATOR_LTE: - rest = new TokenImpl(Token.OPERATOR_EQUALS, "=", - t.getLine(), t.getColumn()+1, t.getOffset()+1); - break; - case TokenTypes.OPERATOR_LSHIFT: - rest = new TokenImpl(Token.OPERATOR_LT, "<", - t.getLine(), t.getColumn()+1, t.getOffset()+1); - break; - case TokenTypes.OPERATOR_LSHIFT_EQUALS: - rest = new TokenImpl(Token.OPERATOR_LTE, "<=", - t.getLine(), t.getColumn()+1, t.getOffset()+1); - break; - } - stack.push(rest); - t = new TokenImpl(Token.OPERATOR_LT, "<", - t.getLine(), t.getColumn(), t.getOffset()); - } - else if (ch=='>') { - Token rest = null; - switch (t.getType()) { - case TokenTypes.OPERATOR_GTE: - rest = new TokenImpl(Token.OPERATOR_EQUALS, "=", - t.getLine(), t.getColumn()+1, t.getOffset()+1); - break; - case TokenTypes.OPERATOR_RSHIFT: - rest = new TokenImpl(Token.OPERATOR_GT, ">", - t.getLine(), t.getColumn()+1, t.getOffset()+1); - break; - case TokenTypes.OPERATOR_RSHIFT2: - rest = new TokenImpl(Token.OPERATOR_RSHIFT, ">>", - t.getLine(), t.getColumn()+1, t.getOffset()+1); - break; - case TokenTypes.OPERATOR_RSHIFT_EQUALS: - rest = new TokenImpl(Token.OPERATOR_GTE, ">=", - t.getLine(), t.getColumn()+1, t.getOffset()+1); - break; - case TokenTypes.OPERATOR_RSHIFT2_EQUALS: - rest = new TokenImpl(Token.OPERATOR_RSHIFT_EQUALS, ">>=", - t.getLine(), t.getColumn()+1, t.getOffset()+1); - break; - } - stack.push(rest); - t = new TokenImpl(Token.OPERATOR_GT, ">", - t.getLine(), t.getColumn(), t.getOffset()); - } - } - } - - debugPrintToken(t); - if (currentResetTokenStack!=null) { - currentResetTokenStack.push(t); - } - if (t!=null) { // Don't let EOS corrupt most recent token - mostRecentToken = t; - } - return t; - - } - - - /** - * Returns the next token from the input stream, or throws an exception - * if the end of stream is reached. - * - * @param error The error description for the exception if the end of - * stream is reached. - * @return The token. - * @throws IOException If an IO error occurs or the end of stream is - * reached. - */ - public Token yylexNonNull(String error) throws IOException { - Token t = yylex(); - if (t==null) { - throw new EOFException(error); - } - return t; - } - - - /** - * Returns the next token from the input stream, or throws an exception - * if the end of stream is reached or if the token is not of a given - * type. - * - * @param type The type the token must be. - * @param error The error description for the exception if the end of - * stream is reached, or if the token is of an unexpected type. - * @return The token. - * @throws IOException If an IO error occurs or the end of stream is - * reached, or if the token is of the wrong type. - */ - public Token yylexNonNull(int type, String error) throws IOException { - return yylexNonNull(type, -1, error); - } - - - /** - * Returns the next token from the input stream, or throws an exception - * if the end of stream is reached or if the token is not of two given - * types. - * - * @param type1 One type the token can be. - * @param type2 Another type the token can be, or -1 if we - * should only check against type1. - * @param error The error description for the exception if the end of - * stream is reached, or if the token is of an unexpected type. - * @return The token. - * @throws IOException If an IO error occurs or the end of stream is - * reached, or if the token is of a wrong type. - */ - public Token yylexNonNull(int type1, int type2, String error) - throws IOException { - return yylexNonNull(type1, type2, -1, error); - } - - - /** - * Returns the next token from the input stream, or throws an exception - * if the end of stream is reached or if the token is not of three given - * types. - * - * @param type1 One type the token can be. - * @param type2 Another type the token can be, or -1 if we - * should only check against type1. - * @param type3 Another type the token can be, or -1 if we - * should only check against type1 and type2. - * @param error The error description for the exception if the end of - * stream is reached, or if the token is of an unexpected type. - * @return The token. - * @throws IOException If an IO error occurs or the end of stream is - * reached, or if the token is of a wrong type. - */ - public Token yylexNonNull(int type1, int type2, int type3, String error) - throws IOException { - Token t = yylex(); - if (t==null) { - throw new IOException(error); - } - if (t.getType()!=type1 && (type2==-1 || t.getType()!=type2) && - (type3==-1 || t.getType()!=type3)) { - throw new IOException(error + ", found '" + t.getLexeme() + "'"); - } - return t; - } - - - /** - * Returns the next token, but does not take it off of the stream. This - * is useful for lookahead. - * - * @return The next token. - * @throws IOException If an IO error occurs. - */ - public Token yyPeek() throws IOException { - Token t = yylex(); - if (t!=null) { - pushOntoStack(t); - } - return t; - } - - - /** - * Returns the depth-th token, but does not anything off of the - * stream. This is useful for lookahead. - * - * @param depth The token to peek at, from 1 forward. - * @return The token, or null if that token index is past the - * end of the stream. - * @throws IOException If an IO error occurs. - */ - public Token yyPeek(int depth) throws IOException { - if (depth<1) { - throw new IllegalArgumentException("depth must be >= 1"); - } - Stack read = new Stack(); - for (int i=0; i-1 if the end of stream - * has been reached. - * @throws IOException If an IO error occurs. - */ - public int yyPeekCheckType() throws IOException { - Token t = yyPeek(); - return t!=null ? t.getType() : -1; - } - - - /** - * Peeks at and returns the type of the specified token on the stream. - * - * @param index The index of the token to retrieve. - * @return The type of the token, or -1 if the end of stream - * was reached first. - * @throws IOException If an IO error occurs. - */ - public int yyPeekCheckType(int index) throws IOException { - Token t = yyPeek(index); - return t!=null ? t.getType() : -1; - } - - - /** - * Returns the next token, but does not take it off of the stream. This - * is useful for lookahead. - * - * @return The next token. - * @throws IOException If an IO error occurs. - */ - public Token yyPeekNonNull(String error) throws IOException { - Token t = yyPeek(); - if (t==null) { - throw new IOException(error); - } - return t; - } - - - /** - * Returns the next token, but does not take it off of the stream. This - * is useful for lookahead. - * - * @param type The type the token must be. - * @return The next token. - * @throws IOException If an IO error occurs, or if EOS is reached, or - * if the token is not of the specified type. - */ - public Token yyPeekNonNull(int type, String error) throws IOException { - return yyPeekNonNull(type, -1, error); - } - - - /** - * Returns the next token, but does not take it off of the stream. This - * is useful for lookahead. - * - * @param type1 One of the two types the token must be. - * @param type2 The other of the two types the token must be. - * @return The next token. - * @throws IOException If an IO error occurs, or if EOS is reached, or - * if the token is not of the specified type. - */ - public Token yyPeekNonNull(int type1, int type2, String error) - throws IOException { - return yyPeekNonNull(type1, type2, -1, error); - } - - - /** - * Returns the next token, but does not take it off of the stream. This - * is useful for lookahead. - * - * @param type1 One of the three types the token must be. - * @param type2 Another of the three types the token must be. - * @param type3 The third of the types the token must be. - * @return The next token. - * @throws IOException If an IO error occurs, or if EOS is reached, or - * if the token is not of the specified type. - */ - public Token yyPeekNonNull(int type1, int type2, int type3, String error) - throws IOException { - Token t = yyPeek(); - if (t==null) { - throw new IOException(error); - } - if (t.getType()!=type1 && (type2==-1 || t.getType()!=type2) && - (type3==-1 || t.getType()!=type3)) { - throw new IOException(error + ", found '" + t.getLexeme() + "'"); - } - return t; - } - - - /** - * Pushes a token back onto the stream. - * - * @param t The token. - */ - public void yyPushback(Token t) { - if (t!=null) { - pushOntoStack(t); - } - } - - - private class DocumentOffset implements Offset { - - public Position pos; - - public DocumentOffset(Position pos) { - this.pos = pos; - } - - public int getOffset() { - return pos.getOffset(); - } - - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/SourceCodeScanner.flex b/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/SourceCodeScanner.flex deleted file mode 100644 index c7075829..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/SourceCodeScanner.flex +++ /dev/null @@ -1,393 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.java.rjc.lexer; - - -/** - * Scanner for the Java programming language.

    - * - * @author Robert Futrell - * @version 0.1 - */ -%% - -%class SourceCodeScanner -%implements org.fife.rsta.ac.java.rjc.lexer.TokenTypes -%unicode -%line -%column -%char -%type org.fife.rsta.ac.java.rjc.lexer.Token - - -%{ - - /** - * Whether comments should be returned as tokens. - */ - private boolean returnComments; - - /** - * Whether whitespace should be returned as tokens. - */ - private boolean returnWhitespace; - - /** - * Whether the last documentation comment parsed should be kept. - */ - private boolean keepLastDocComment; - - /** - * The last documentation comment parsed, if that feature is enabled. - */ - private String lastDocComment; - - - private Token createToken(int type) { - return createToken(type, false); - } - - - private Token createToken(int type, boolean invalid) { - return new TokenImpl(type, yytext(), yyline, yycolumn, yychar, invalid); - } - - - /** - * Returns the current column into the current line. - * - * @return The current column. - */ - public int getColumn() { - return yycolumn; - } - - - /** - * Returns the last documentation comment parsed, if this feature is - * enabled. - * - * @return The last documentation comment parsed, or null - * if the feature is disabled. - * @see #setKeepLastDocComment(boolean) - */ - public String getLastDocComment() { - return lastDocComment; - } - - - /** - * Returns the current line into the document. - * - * @return The current line. - */ - public int getLine() { - return yyline; - } - - - /** - * Returns the current offset into the document. - * - * @return The offset. - */ - public int getOffset() { - return yychar; - } - - - /** - * Returns whether comments are returned as tokens. - * - * @return Whether comments are returned as tokens. - * @see #getReturnWhitespace() - */ - public boolean getReturnComments() { - return returnComments; - } - - - /** - * Returns whether whitespace is returned as tokens. - * - * @return Whether whitespace is returned as tokens. - * @see #getReturnComments() - */ - public boolean getReturnWhitespace() { - return returnWhitespace; - } - - - /** - * Sets whether the last documentation comment should be kept. - * - * @param keep Whether to keep the last documentation comment. - * @see #getLastDocComment() - */ - public void setKeepLastDocComment(boolean keep) { - keepLastDocComment = keep; - } - - - /** - * Sets whether comments are returned as tokens. - * - * @param returnComments Whether comments should be returned as tokens. - * @see #getReturnComments() - * @see #setReturnWhitespace(boolean) - */ - public void setReturnComments(boolean returnComments) { - this.returnComments = returnComments; - } - - - /** - * Sets whether whitespace is returned as tokens. - * - * @param returnWhitespace Whether whitespace should be returned as tokens. - * @see #getReturnWhitespace() - * @see #setReturnComments(boolean) - */ - public void setReturnWhitespace(boolean returnWhitespace) { - this.returnWhitespace = returnWhitespace; - } - - -%} - -/* JLS 3.3 - Unicode Escapes */ -UnicodeInputCharacter = ({UnicodeEscape}|{RawInputCharacter}) -UnicodeEscape = ([\\]{UnicodeMarker}{HexDigit}{4}) -UnicodeMarker = ("u"|{UnicodeMarker}"u") -RawInputCharacter = (.) - -/* JLS 3.4 - Line Terminators */ -LineTerminator = (\r|\n|\r\n) -// JFlex has some trouble compiling InputCharacter... -//InputCharacter = ({UnicodeInputCharacter}|[^\r\n]) -InputCharacter = ([\\][u]+{HexDigit}{4}|[^\r\n]) - -/* JLS 3.6 - White Space */ -WhiteSpace = (([ \t\f]|{LineTerminator})+) - -/* JLS 3.7 - Comments (made non-recursive for JFlex) */ -DocumentationComment = ("/*" "*"+ [^/*] ~"*/") -Comment = ({TraditionalComment}|{EndOfLineComment}) -TraditionalComment = ("/*" [^*] ~"*/" | "/*" "*"+ "/") -EndOfLineComment = ("//" {CharactersInLine}?) -CharactersInLine = ({InputCharacter}+) - -/* JLS 3.8 - Identifiers (made non-recursive for JFlex) */ -Identifier = ({IdentifierChars}) /* but not Keyword, BooleanLiteral, NullLiteral */ -IdentifierChars = ({JavaLetter}{JavaLetterOrDigit}*) -JavaLetter = ([:jletter:]) -JavaLetterOrDigit = ([:jletterdigit:]) - -/* JLS 3.10.1 - Integer Literals */ -IntegerLiteral = ({DecimalIntegerLiteral}|{HexIntegerLiteral}|{OctalIntegerLiteral}) -DecimalIntegerLiteral = ({DecimalNumeral}{IntegerTypeSuffix}?) -HexIntegerLiteral = ({HexNumeral}{IntegerTypeSuffix}?) -OctalIntegerLiteral = ({OctalNumeral}{IntegerTypeSuffix}?) -IntegerTypeSuffix = ([lL]) -DecimalNumeral = ("0"|{NonZeroDigit}{Digits}?) -Digits = ({Digit}+) -Digit = ("0"|{NonZeroDigit}) -NonZeroDigit = ([1-9]) -HexNumeral = ("0"[xX]{HexDigits}) -HexDigits = ({HexDigit}+) -HexDigit = ([0-9a-fA-F]) -OctalNumeral = ("0"{OctalDigits}) -OctalDigits = ({OctalDigit}+) -OctalDigit = ([0-7]) - -/* JLS 3.10.2 - Floating Point Literals */ -/* TODO*/ -FloatingPointLiteral = ([0-9]+[\.][0-9]+[fF]) - -/* JLS 3.10.3 - Boolean Literals */ -BooleanLiteral = ("true"|"false") - -/* JLS 3.10.4 - Character Literals */ -CharacterLiteral = ([\']({SingleCharacter}|{EscapeSequence})[\']) -SingleCharacter = ([\\][u]+{HexDigit}{4}|[^\r\n\'\\]) -InvalidCharLiteral = ([\'][^\']*[\']?) - -/* JLS 3.10.5 - String Literals */ -StringLiteral = ([\"]{StringCharacters}*[\"]) -StringCharacters = ({StringCharacter}+) -StringCharacter = ([\\][u]+{HexDigit}{4}|[^\r\n\"\\]|{EscapeSequence}) -//StringCharacter = ([^\r\n\"\\]|{EscapeSequence}) -InvalidStringLiteral = ([\"][^\"]*[\"]?) - -/* JLS 3.10.6 - Escape Sequences for Character and String Literals */ -EscapeSequence = ([\\][btnfr\"\'\\]|{OctalEscape}) -OctalEscape = ([\\]({OctalDigit}{OctalDigit}?|{ZeroToThree}{OctalDigit}{OctalDigit})) -OctalDigit = ([0-7]) -ZeroToThree = ([0-3]) - -/* JLS 3.10.7 - The Null Literal */ -NullLiteral = ("null") - -/* ??? - Stuff not in JLS */ -AnnotationStart = ([\@]) -Elipsis = ("...") - - -%% - - { - - {WhiteSpace} { - if (returnWhitespace) { - return createToken(Token.WHITESPACE); - } - } - - {DocumentationComment} { - if (keepLastDocComment) { - lastDocComment = yytext(); - } - if (returnComments) { - return createToken(Token.DOC_COMMENT); - } - } - - {Comment} { - if (returnComments) { - return createToken(Token.COMMENT); - } - } - - /* Keywords */ - "abstract" { return createToken(KEYWORD_ABSTRACT); } - "assert" { return createToken(KEYWORD_ASSERT); } - "break" { return createToken(KEYWORD_BREAK); } - "case" { return createToken(KEYWORD_CASE); } - "catch" { return createToken(KEYWORD_CATCH); } - "class" { return createToken(KEYWORD_CLASS); } - "const" { return createToken(KEYWORD_CONST); } - "continue" { return createToken(KEYWORD_CONTINUE); } - "default" { return createToken(KEYWORD_DEFAULT); } - "do" { return createToken(KEYWORD_DO); } - "else" { return createToken(KEYWORD_ELSE); } - "enum" { return createToken(KEYWORD_ENUM); } - "extends" { return createToken(KEYWORD_EXTENDS); } - "final" { return createToken(KEYWORD_FINAL); } - "finally" { return createToken(KEYWORD_FINALLY); } - "for" { return createToken(KEYWORD_FOR); } - "goto" { return createToken(KEYWORD_GOTO); } - "if" { return createToken(KEYWORD_IF); } - "implements" { return createToken(KEYWORD_IMPLEMENTS); } - "import" { return createToken(KEYWORD_IMPORT); } - "instanceof" { return createToken(KEYWORD_INSTANCEOF); } - "interface" { return createToken(KEYWORD_INTERFACE); } - "native" { return createToken(KEYWORD_NATIVE); } - "new" { return createToken(KEYWORD_NEW); } - "package" { return createToken(KEYWORD_PACKAGE); } - "private" { return createToken(KEYWORD_PRIVATE); } - "protected" { return createToken(KEYWORD_PROTECTED); } - "public" { return createToken(KEYWORD_PUBLIC); } - "return" { return createToken(KEYWORD_RETURN); } - "static" { return createToken(KEYWORD_STATIC); } - "strictfp" { return createToken(KEYWORD_STRICTFP); } - "super" { return createToken(KEYWORD_SUPER); } - "switch" { return createToken(KEYWORD_SWITCH); } - "synchronized" { return createToken(KEYWORD_SYNCHRONIZED); } - "this" { return createToken(KEYWORD_THIS); } - "throw" { return createToken(KEYWORD_THROW); } - "throws" { return createToken(KEYWORD_THROWS); } - "transient" { return createToken(KEYWORD_TRANSIENT); } - "try" { return createToken(KEYWORD_TRY); } - "void" { return createToken(KEYWORD_VOID); } - "volatile" { return createToken(KEYWORD_VOLATILE); } - "while" { return createToken(KEYWORD_WHILE); } - - /* Data types */ - "boolean" { return createToken(KEYWORD_BOOLEAN); } - "byte" { return createToken(KEYWORD_BYTE); } - "char" { return createToken(KEYWORD_CHAR); } - "double" { return createToken(KEYWORD_DOUBLE); } - "float" { return createToken(KEYWORD_FLOAT); } - "int" { return createToken(KEYWORD_INT); } - "long" { return createToken(KEYWORD_LONG); } - "short" { return createToken(KEYWORD_SHORT); } - - /* Literals */ - {IntegerLiteral} { return createToken(LITERAL_INT); } - {FloatingPointLiteral} { return createToken(LITERAL_FP); } - {BooleanLiteral} { return createToken(LITERAL_BOOLEAN); } - {CharacterLiteral} { return createToken(LITERAL_CHAR); } - {StringLiteral} { return createToken(LITERAL_STRING); } - {NullLiteral} { return createToken(LITERAL_NULL); } - {InvalidCharLiteral} { return createToken(LITERAL_CHAR, true); } - {InvalidStringLiteral} { return createToken(LITERAL_STRING, true); } - - {Identifier} { return createToken(IDENTIFIER); } - - {AnnotationStart} { return createToken(ANNOTATION_START); } - - {Elipsis} { return createToken(ELIPSIS); } - - /* Separators (JLS 3.11) */ - "(" { return createToken(SEPARATOR_LPAREN); } - ")" { return createToken(SEPARATOR_RPAREN); } - "{" { return createToken(SEPARATOR_LBRACE); } - "}" { return createToken(SEPARATOR_RBRACE); } - "[" { return createToken(SEPARATOR_LBRACKET); } - "]" { return createToken(SEPARATOR_RBRACKET); } - ";" { return createToken(SEPARATOR_SEMICOLON); } - "," { return createToken(SEPARATOR_COMMA); } - "." { return createToken(SEPARATOR_DOT); } - - /* Operators (JLS 3.12) */ - "=" { return createToken(OPERATOR_EQUALS); } - ">" { return createToken(OPERATOR_GT); } - "<" { return createToken(OPERATOR_LT); } - "!" { return createToken(OPERATOR_LOGICAL_NOT); } - "~" { return createToken(OPERATOR_BITWISE_NOT); } - "?" { return createToken(OPERATOR_QUESTION); } - ":" { return createToken(OPERATOR_COLON); } - "==" { return createToken(OPERATOR_EQUALS_EQUALS); } - "<=" { return createToken(OPERATOR_LTE); } - ">=" { return createToken(OPERATOR_GTE); } - "!=" { return createToken(OPERATOR_NE); } - "&&" { return createToken(OPERATOR_LOGICAL_AND); } - "||" { return createToken(OPERATOR_LOGICAL_OR); } - "++" { return createToken(OPERATOR_INCREMENT); } - "--" { return createToken(OPERATOR_DECREMENT); } - "+" { return createToken(OPERATOR_PLUS); } - "-" { return createToken(OPERATOR_MINUS); } - "*" { return createToken(OPERATOR_TIMES); } - "/" { return createToken(OPERATOR_DIVIDE); } - "&" { return createToken(OPERATOR_BITWISE_AND); } - "|" { return createToken(OPERATOR_BITWISE_OR); } - "^" { return createToken(OPERATOR_BITWISE_XOR); } - "%" { return createToken(OPERATOR_MOD); } - "<<" { return createToken(OPERATOR_LSHIFT); } - ">>" { return createToken(OPERATOR_RSHIFT); } - ">>>" { return createToken(OPERATOR_RSHIFT2); } - "+=" { return createToken(OPERATOR_PLUS_EQUALS); } - "-=" { return createToken(OPERATOR_MINUS_EQUALS); } - "*=" { return createToken(OPERATOR_TIMES_EQUALS); } - "/=" { return createToken(OPERATOR_DIVIDE_EQUALS); } - "&=" { return createToken(OPERATOR_BITWISE_AND_EQUALS); } - "|=" { return createToken(OPERATOR_BITWISE_OR_EQUALS); } - "^=" { return createToken(OPERATOR_BITWISE_XOR_EQUALS); } - "%=" { return createToken(OPERATOR_MOD_EQUALS); } - "<<=" { return createToken(OPERATOR_LSHIFT_EQUALS); } - ">>=" { return createToken(OPERATOR_RSHIFT_EQUALS); } - ">>>=" { return createToken(OPERATOR_RSHIFT2_EQUALS); } - - - /* Unhandled stuff. */ - . { return createToken(IDENTIFIER, true); } - -} diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/SourceCodeScanner.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/SourceCodeScanner.java deleted file mode 100644 index f8a5f1ae..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/SourceCodeScanner.java +++ /dev/null @@ -1,1663 +0,0 @@ -/* The following code was generated by JFlex 1.4.1 on 3/31/10 5:27 PM */ - -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.rjc.lexer; - - -/** - * Scanner for the Java programming language.

    - * - * @author Robert Futrell - * @version 0.1 - */ - -class SourceCodeScanner implements org.fife.rsta.ac.bsh.rjc.lexer.TokenTypes { - - /** This character denotes the end of file */ - public static final int YYEOF = -1; - - /** initial size of the lookahead buffer */ - private static final int ZZ_BUFFERSIZE = 16384; - - /** lexical states */ - public static final int YYINITIAL = 0; - - /** - * Translates characters to character classes - */ - private static final String ZZ_CMAP_PACKED = - "\11\10\1\4\1\3\1\0\1\4\1\3\16\10\4\0\1\4\1\67"+ - "\1\31\1\0\1\7\1\100\1\73\1\30\1\54\1\55\1\6\1\75"+ - "\1\63\1\76\1\17\1\5\1\12\3\34\4\16\2\13\1\72\1\62"+ - "\1\66\1\64\1\65\1\71\1\35\5\15\1\20\5\7\1\11\13\7"+ - "\1\14\2\7\1\60\1\1\1\61\1\77\1\7\1\0\1\25\1\33"+ - "\1\36\1\43\1\23\1\24\1\47\1\40\1\42\1\7\1\37\1\26"+ - "\1\44\1\32\1\41\1\50\1\7\1\22\1\27\1\21\1\2\1\51"+ - "\1\52\1\45\1\46\1\53\1\56\1\74\1\57\1\70\41\10\2\0"+ - "\4\7\4\0\1\7\2\0\1\10\7\0\1\7\4\0\1\7\5\0"+ - "\27\7\1\0\37\7\1\0\u013f\7\31\0\162\7\4\0\14\7\16\0"+ - "\5\7\11\0\1\7\21\0\130\10\5\0\23\10\12\0\1\7\13\0"+ - "\1\7\1\0\3\7\1\0\1\7\1\0\24\7\1\0\54\7\1\0"+ - "\46\7\1\0\5\7\4\0\202\7\1\0\4\10\3\0\105\7\1\0"+ - "\46\7\2\0\2\7\6\0\20\7\41\0\46\7\2\0\1\7\7\0"+ - "\47\7\11\0\21\10\1\0\27\10\1\0\3\10\1\0\1\10\1\0"+ - "\2\10\1\0\1\10\13\0\33\7\5\0\3\7\15\0\4\10\14\0"+ - "\6\10\13\0\32\7\5\0\13\7\16\10\7\0\12\10\4\0\2\7"+ - "\1\10\143\7\1\0\1\7\10\10\1\0\6\10\2\7\2\10\1\0"+ - "\4\10\2\7\12\10\3\7\2\0\1\7\17\0\1\10\1\7\1\10"+ - "\36\7\33\10\2\0\3\7\60\0\46\7\13\10\1\7\u014f\0\3\10"+ - "\66\7\2\0\1\10\1\7\20\10\2\0\1\7\4\10\3\0\12\7"+ - "\2\10\2\0\12\10\21\0\3\10\1\0\10\7\2\0\2\7\2\0"+ - "\26\7\1\0\7\7\1\0\1\7\3\0\4\7\2\0\1\10\1\7"+ - "\7\10\2\0\2\10\2\0\3\10\11\0\1\10\4\0\2\7\1\0"+ - "\3\7\2\10\2\0\12\10\4\7\15\0\3\10\1\0\6\7\4\0"+ - "\2\7\2\0\26\7\1\0\7\7\1\0\2\7\1\0\2\7\1\0"+ - "\2\7\2\0\1\10\1\0\5\10\4\0\2\10\2\0\3\10\13\0"+ - "\4\7\1\0\1\7\7\0\14\10\3\7\14\0\3\10\1\0\11\7"+ - "\1\0\3\7\1\0\26\7\1\0\7\7\1\0\2\7\1\0\5\7"+ - "\2\0\1\10\1\7\10\10\1\0\3\10\1\0\3\10\2\0\1\7"+ - "\17\0\2\7\2\10\2\0\12\10\1\0\1\7\17\0\3\10\1\0"+ - "\10\7\2\0\2\7\2\0\26\7\1\0\7\7\1\0\2\7\1\0"+ - "\5\7\2\0\1\10\1\7\6\10\3\0\2\10\2\0\3\10\10\0"+ - "\2\10\4\0\2\7\1\0\3\7\4\0\12\10\1\0\1\7\20\0"+ - "\1\10\1\7\1\0\6\7\3\0\3\7\1\0\4\7\3\0\2\7"+ - "\1\0\1\7\1\0\2\7\3\0\2\7\3\0\3\7\3\0\10\7"+ - "\1\0\3\7\4\0\5\10\3\0\3\10\1\0\4\10\11\0\1\10"+ - "\17\0\11\10\11\0\1\7\7\0\3\10\1\0\10\7\1\0\3\7"+ - "\1\0\27\7\1\0\12\7\1\0\5\7\4\0\7\10\1\0\3\10"+ - "\1\0\4\10\7\0\2\10\11\0\2\7\4\0\12\10\22\0\2\10"+ - "\1\0\10\7\1\0\3\7\1\0\27\7\1\0\12\7\1\0\5\7"+ - "\2\0\1\10\1\7\7\10\1\0\3\10\1\0\4\10\7\0\2\10"+ - "\7\0\1\7\1\0\2\7\4\0\12\10\22\0\2\10\1\0\10\7"+ - "\1\0\3\7\1\0\27\7\1\0\20\7\4\0\6\10\2\0\3\10"+ - "\1\0\4\10\11\0\1\10\10\0\2\7\4\0\12\10\22\0\2\10"+ - "\1\0\22\7\3\0\30\7\1\0\11\7\1\0\1\7\2\0\7\7"+ - "\3\0\1\10\4\0\6\10\1\0\1\10\1\0\10\10\22\0\2\10"+ - "\15\0\60\7\1\10\2\7\7\10\4\0\10\7\10\10\1\0\12\10"+ - "\47\0\2\7\1\0\1\7\2\0\2\7\1\0\1\7\2\0\1\7"+ - "\6\0\4\7\1\0\7\7\1\0\3\7\1\0\1\7\1\0\1\7"+ - "\2\0\2\7\1\0\4\7\1\10\2\7\6\10\1\0\2\10\1\7"+ - "\2\0\5\7\1\0\1\7\1\0\6\10\2\0\12\10\2\0\2\7"+ - "\42\0\1\7\27\0\2\10\6\0\12\10\13\0\1\10\1\0\1\10"+ - "\1\0\1\10\4\0\2\10\10\7\1\0\42\7\6\0\24\10\1\0"+ - "\2\10\4\7\4\0\10\10\1\0\44\10\11\0\1\10\71\0\42\7"+ - "\1\0\5\7\1\0\2\7\1\0\7\10\3\0\4\10\6\0\12\10"+ - "\6\0\6\7\4\10\106\0\46\7\12\0\51\7\7\0\132\7\5\0"+ - "\104\7\5\0\122\7\6\0\7\7\1\0\77\7\1\0\1\7\1\0"+ - "\4\7\2\0\7\7\1\0\1\7\1\0\4\7\2\0\47\7\1\0"+ - "\1\7\1\0\4\7\2\0\37\7\1\0\1\7\1\0\4\7\2\0"+ - "\7\7\1\0\1\7\1\0\4\7\2\0\7\7\1\0\7\7\1\0"+ - "\27\7\1\0\37\7\1\0\1\7\1\0\4\7\2\0\7\7\1\0"+ - "\47\7\1\0\23\7\16\0\11\10\56\0\125\7\14\0\u026c\7\2\0"+ - "\10\7\12\0\32\7\5\0\113\7\3\0\3\7\17\0\15\7\1\0"+ - "\4\7\3\10\13\0\22\7\3\10\13\0\22\7\2\10\14\0\15\7"+ - "\1\0\3\7\1\0\2\10\14\0\64\7\40\10\3\0\1\7\3\0"+ - "\2\7\1\10\2\0\12\10\41\0\3\10\2\0\12\10\6\0\130\7"+ - "\10\0\51\7\1\10\126\0\35\7\3\0\14\10\4\0\14\10\12\0"+ - "\12\10\36\7\2\0\5\7\u038b\0\154\7\224\0\234\7\4\0\132\7"+ - "\6\0\26\7\2\0\6\7\2\0\46\7\2\0\6\7\2\0\10\7"+ - "\1\0\1\7\1\0\1\7\1\0\1\7\1\0\37\7\2\0\65\7"+ - "\1\0\7\7\1\0\1\7\3\0\3\7\1\0\7\7\3\0\4\7"+ - "\2\0\6\7\4\0\15\7\5\0\3\7\1\0\7\7\17\0\4\10"+ - "\32\0\5\10\20\0\2\7\23\0\1\7\13\0\4\10\6\0\6\10"+ - "\1\0\1\7\15\0\1\7\40\0\22\7\36\0\15\10\4\0\1\10"+ - "\3\0\6\10\27\0\1\7\4\0\1\7\2\0\12\7\1\0\1\7"+ - "\3\0\5\7\6\0\1\7\1\0\1\7\1\0\1\7\1\0\4\7"+ - "\1\0\3\7\1\0\7\7\3\0\3\7\5\0\5\7\26\0\44\7"+ - "\u0e81\0\3\7\31\0\11\7\6\10\1\0\5\7\2\0\5\7\4\0"+ - "\126\7\2\0\2\10\2\0\3\7\1\0\137\7\5\0\50\7\4\0"+ - "\136\7\21\0\30\7\70\0\20\7\u0200\0\u19b6\7\112\0\u51a6\7\132\0"+ - "\u048d\7\u0773\0\u2ba4\7\u215c\0\u012e\7\2\0\73\7\225\0\7\7\14\0"+ - "\5\7\5\0\1\7\1\10\12\7\1\0\15\7\1\0\5\7\1\0"+ - "\1\7\1\0\2\7\1\0\2\7\1\0\154\7\41\0\u016b\7\22\0"+ - "\100\7\2\0\66\7\50\0\15\7\3\0\20\10\20\0\4\10\17\0"+ - "\2\7\30\0\3\7\31\0\1\7\6\0\5\7\1\0\207\7\2\0"+ - "\1\10\4\0\1\7\13\0\12\10\7\0\32\7\4\0\1\7\1\0"+ - "\32\7\12\0\132\7\3\0\6\7\2\0\6\7\2\0\6\7\2\0"+ - "\3\7\3\0\2\7\3\0\2\7\22\0\3\10\4\0"; - - /** - * Translates characters to character classes - */ - private static final char [] ZZ_CMAP = zzUnpackCMap(ZZ_CMAP_PACKED); - - /** - * Translates DFA states to action switch labels. - */ - private static final int [] ZZ_ACTION = zzUnpackAction(); - - private static final String ZZ_ACTION_PACKED_0 = - "\1\0\1\1\1\2\1\3\1\4\1\5\2\6\1\7"+ - "\7\2\1\10\1\11\2\2\1\12\7\2\1\13\1\14"+ - "\1\15\1\16\1\17\1\20\1\21\1\22\1\23\1\24"+ - "\1\25\1\26\1\27\1\30\1\31\1\32\1\33\1\34"+ - "\1\35\1\36\1\37\1\40\1\0\1\41\1\42\2\6"+ - "\4\0\22\2\4\10\2\11\1\43\12\2\1\44\3\2"+ - "\1\45\6\2\1\46\1\47\1\50\1\51\1\52\1\53"+ - "\1\54\1\55\1\56\1\57\1\60\1\61\1\62\1\63"+ - "\1\64\1\65\2\0\1\6\1\0\1\66\2\2\1\67"+ - "\10\2\1\70\12\2\1\71\4\10\3\11\1\2\1\72"+ - "\11\2\1\73\14\2\1\74\1\75\1\76\2\0\1\40"+ - "\1\77\1\100\2\2\1\101\1\2\1\102\1\103\5\2"+ - "\1\104\6\2\1\10\1\11\2\0\1\105\3\2\1\106"+ - "\1\2\1\107\1\2\1\110\10\2\1\111\5\2\1\112"+ - "\1\2\1\113\1\0\1\2\1\114\2\2\1\115\1\116"+ - "\2\2\1\117\2\2\1\120\2\2\1\10\1\11\1\0"+ - "\1\2\1\121\1\2\1\122\1\123\1\2\1\124\13\2"+ - "\1\125\1\126\1\2\1\127\1\130\2\2\1\131\2\2"+ - "\1\132\1\2\1\133\1\10\1\11\1\0\1\134\5\2"+ - "\1\135\1\2\1\136\1\137\5\2\1\140\1\141\3\2"+ - "\1\0\1\142\4\2\1\143\1\2\1\144\1\145\2\2"+ - "\1\146\1\147\1\2\1\0\1\150\4\2\1\151\1\152"+ - "\1\2\1\153\2\2\1\154\1\2\1\155\1\156\1\2"+ - "\1\157"; - - private static int [] zzUnpackAction() { - int [] result = new int[341]; - int offset = 0; - offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); - return result; - } - - private static int zzUnpackAction(String packed, int offset, int [] result) { - int i = 0; /* index in packed string */ - int j = offset; /* index in unpacked array */ - int l = packed.length(); - while (i < l) { - int count = packed.charAt(i++); - int value = packed.charAt(i++); - do result[j++] = value; while (--count > 0); - } - return j; - } - - - /** - * Translates a state to a row index in the transition table - */ - private static final int [] ZZ_ROWMAP = zzUnpackRowMap(); - - private static final String ZZ_ROWMAP_PACKED_0 = - "\0\0\0\101\0\202\0\303\0\u0104\0\u0145\0\u0186\0\u01c7"+ - "\0\u0208\0\u0249\0\u028a\0\u02cb\0\u030c\0\u034d\0\u038e\0\u03cf"+ - "\0\u0410\0\u0451\0\u0492\0\u04d3\0\101\0\u0514\0\u0555\0\u0596"+ - "\0\u05d7\0\u0618\0\u0659\0\u069a\0\101\0\101\0\101\0\101"+ - "\0\101\0\101\0\101\0\101\0\u06db\0\u071c\0\u075d\0\u079e"+ - "\0\101\0\101\0\101\0\u07df\0\u0820\0\u0861\0\u08a2\0\u08e3"+ - "\0\u0924\0\u0965\0\u09a6\0\101\0\101\0\101\0\u09e7\0\u0a28"+ - "\0\u0a69\0\u0aaa\0\u0aeb\0\u0b2c\0\u0b6d\0\u0bae\0\u0bef\0\u0c30"+ - "\0\u0c71\0\u0cb2\0\u0cf3\0\u0d34\0\u0d75\0\u0db6\0\u0df7\0\u0e38"+ - "\0\u0e79\0\u0eba\0\u0efb\0\u0f3c\0\u0f7d\0\u0fbe\0\u0fff\0\u1040"+ - "\0\101\0\u1081\0\u10c2\0\101\0\u1103\0\u1144\0\u1185\0\u11c6"+ - "\0\u1207\0\u1248\0\u1289\0\u12ca\0\u130b\0\u134c\0\202\0\u138d"+ - "\0\u13ce\0\u140f\0\u1450\0\u1491\0\u14d2\0\u1513\0\u1554\0\u1595"+ - "\0\u15d6\0\101\0\101\0\u1617\0\101\0\u1658\0\101\0\101"+ - "\0\101\0\101\0\101\0\101\0\101\0\101\0\101\0\101"+ - "\0\101\0\u1699\0\u16da\0\u171b\0\u175c\0\101\0\u179d\0\u17de"+ - "\0\202\0\u181f\0\u1860\0\u18a1\0\u18e2\0\u1923\0\u1964\0\u19a5"+ - "\0\u19e6\0\202\0\u1a27\0\u1a68\0\u1aa9\0\u1aea\0\u1b2b\0\u1b6c"+ - "\0\u1bad\0\u1bee\0\u1c2f\0\u1c70\0\101\0\u1cb1\0\u1cf2\0\u1d33"+ - "\0\u1d74\0\u1db5\0\u1df6\0\101\0\u1e37\0\202\0\u1e78\0\u1eb9"+ - "\0\u1efa\0\u1f3b\0\u1f7c\0\u1fbd\0\u1ffe\0\u203f\0\u2080\0\u20c1"+ - "\0\u2102\0\u2143\0\u2184\0\u21c5\0\u2206\0\u2247\0\u2288\0\u22c9"+ - "\0\u230a\0\u234b\0\u238c\0\u23cd\0\101\0\u240e\0\101\0\u244f"+ - "\0\u2490\0\101\0\101\0\202\0\u24d1\0\u2512\0\202\0\u2553"+ - "\0\202\0\202\0\u2594\0\u25d5\0\u2616\0\u2657\0\u2698\0\202"+ - "\0\u26d9\0\u271a\0\u275b\0\u279c\0\u27dd\0\u281e\0\u285f\0\u28a0"+ - "\0\u1df6\0\u28e1\0\202\0\u2922\0\u2963\0\u29a4\0\202\0\u29e5"+ - "\0\202\0\u2a26\0\202\0\u2a67\0\u2aa8\0\u2ae9\0\u2b2a\0\u2b6b"+ - "\0\u2bac\0\u2bed\0\u2c2e\0\202\0\u2c6f\0\u2cb0\0\u2cf1\0\u2d32"+ - "\0\u2d73\0\202\0\u2db4\0\101\0\u2df5\0\u2e36\0\u2e77\0\u2eb8"+ - "\0\u2ef9\0\202\0\u2f3a\0\u2f7b\0\u2fbc\0\202\0\u2ffd\0\u303e"+ - "\0\202\0\u307f\0\u30c0\0\u3101\0\u3142\0\u3183\0\u31c4\0\202"+ - "\0\u3205\0\202\0\202\0\u3246\0\202\0\u3287\0\u32c8\0\u3309"+ - "\0\u334a\0\u338b\0\u33cc\0\u340d\0\u344e\0\u348f\0\u34d0\0\u3511"+ - "\0\202\0\101\0\u3552\0\202\0\202\0\u3593\0\u35d4\0\202"+ - "\0\u3615\0\u3656\0\202\0\u3697\0\202\0\u36d8\0\u3719\0\u375a"+ - "\0\202\0\u379b\0\u37dc\0\u381d\0\u385e\0\u389f\0\202\0\u38e0"+ - "\0\202\0\202\0\u3921\0\u3962\0\u39a3\0\u39e4\0\u3a25\0\202"+ - "\0\202\0\u3a66\0\u3aa7\0\u3ae8\0\u3b29\0\202\0\u3b6a\0\u3bab"+ - "\0\u3bec\0\u3c2d\0\202\0\u3c6e\0\202\0\202\0\u3caf\0\u3cf0"+ - "\0\202\0\202\0\u3d31\0\u3d72\0\202\0\u3db3\0\u3df4\0\u3e35"+ - "\0\u3e76\0\202\0\202\0\u3eb7\0\202\0\u3ef8\0\u3f39\0\202"+ - "\0\u3f7a\0\202\0\202\0\u3fbb\0\202"; - - private static int [] zzUnpackRowMap() { - int [] result = new int[341]; - int offset = 0; - offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); - return result; - } - - private static int zzUnpackRowMap(String packed, int offset, int [] result) { - int i = 0; /* index in packed string */ - int j = offset; /* index in unpacked array */ - int l = packed.length(); - while (i < l) { - int high = packed.charAt(i++) << 16; - result[j++] = high | packed.charAt(i++); - } - return j; - } - - /** - * The transition table of the DFA - */ - private static final int [] ZZ_TRANS = zzUnpackTrans(); - - private static final String ZZ_TRANS_PACKED_0 = - "\2\2\1\3\2\4\1\5\1\6\1\3\1\2\1\3"+ - "\1\7\1\10\2\3\1\10\1\11\1\3\1\12\1\13"+ - "\1\14\1\15\1\16\1\17\1\20\1\21\1\22\1\23"+ - "\1\24\1\10\1\25\1\26\3\3\1\27\1\30\3\3"+ - "\1\31\1\32\1\33\1\34\1\3\1\35\1\36\1\37"+ - "\1\40\1\41\1\42\1\43\1\44\1\45\1\46\1\47"+ - "\1\50\1\51\1\52\1\53\1\54\1\55\1\56\1\57"+ - "\1\60\1\61\103\0\1\3\4\0\10\3\1\0\10\3"+ - "\2\0\3\3\1\0\16\3\30\0\2\4\101\0\1\62"+ - "\1\63\55\0\1\64\100\0\1\65\25\0\1\66\1\67"+ - "\1\70\1\71\1\0\1\67\1\72\6\0\1\66\5\0"+ - "\1\67\10\0\1\71\44\0\1\66\2\10\2\0\1\10"+ - "\1\72\6\0\1\66\5\0\1\10\63\0\1\73\63\0"+ - "\1\3\4\0\10\3\1\0\2\3\1\74\5\3\2\0"+ - "\3\3\1\0\2\3\1\75\13\3\27\0\1\3\4\0"+ - "\10\3\1\0\3\3\1\76\4\3\2\0\3\3\1\0"+ - "\16\3\27\0\1\3\4\0\10\3\1\0\6\3\1\77"+ - "\1\3\2\0\1\100\2\3\1\0\7\3\1\101\6\3"+ - "\27\0\1\3\4\0\10\3\1\0\5\3\1\102\1\103"+ - "\1\3\2\0\3\3\1\0\3\3\1\104\1\105\11\3"+ - "\27\0\1\3\4\0\10\3\1\0\7\3\1\106\2\0"+ - "\1\3\1\107\1\3\1\0\16\3\27\0\1\3\4\0"+ - "\10\3\1\0\10\3\2\0\3\3\1\0\3\3\1\110"+ - "\12\3\27\0\1\111\4\0\10\3\1\0\1\3\1\112"+ - "\6\3\2\0\3\3\1\0\2\3\1\113\5\3\1\114"+ - "\3\3\1\115\1\3\25\0\1\116\1\117\1\116\1\120"+ - "\24\116\1\121\50\116\1\22\1\122\1\22\1\123\25\22"+ - "\1\124\47\22\2\0\1\125\4\0\10\3\1\0\3\3"+ - "\1\126\1\3\1\127\2\3\2\0\3\3\1\0\16\3"+ - "\27\0\1\3\4\0\10\3\1\0\2\3\1\130\5\3"+ - "\2\0\3\3\1\0\3\3\1\131\4\3\1\132\5\3"+ - "\27\0\1\3\4\0\10\3\1\0\5\3\1\133\1\134"+ - "\1\3\2\0\3\3\1\0\2\3\1\135\1\136\12\3"+ - "\27\0\1\3\4\0\10\3\1\0\4\3\1\137\3\3"+ - "\2\0\1\140\2\3\1\0\6\3\1\141\7\3\27\0"+ - "\1\3\4\0\10\3\1\0\3\3\1\142\4\3\2\0"+ - "\3\3\1\0\3\3\1\143\12\3\27\0\1\3\4\0"+ - "\10\3\1\0\10\3\2\0\3\3\1\0\3\3\1\144"+ - "\12\3\27\0\1\145\4\0\10\3\1\0\2\3\1\146"+ - "\2\3\1\147\2\3\2\0\3\3\1\0\16\3\27\0"+ - "\1\3\4\0\10\3\1\0\10\3\2\0\3\3\1\0"+ - "\3\3\1\150\12\3\27\0\1\3\4\0\10\3\1\0"+ - "\10\3\2\0\3\3\1\0\2\3\1\151\13\3\111\0"+ - "\1\152\100\0\1\153\1\154\77\0\1\155\1\0\1\156"+ - "\76\0\1\157\100\0\1\160\6\0\1\161\71\0\1\162"+ - "\7\0\1\163\70\0\1\164\10\0\1\165\67\0\1\166"+ - "\11\0\1\167\66\0\1\170\100\0\1\171\14\0\3\62"+ - "\1\0\75\62\6\172\1\173\72\172\11\0\1\66\1\67"+ - "\1\70\2\0\1\67\1\72\6\0\1\66\5\0\1\67"+ - "\56\0\2\70\2\0\1\70\1\72\14\0\1\70\56\0"+ - "\2\174\1\0\2\174\1\0\1\174\2\0\3\174\5\0"+ - "\2\174\1\0\1\174\4\0\1\174\47\0\2\175\2\0"+ - "\1\175\15\0\1\175\63\0\1\176\63\0\1\177\4\0"+ - "\10\3\1\0\5\3\1\200\2\3\2\0\3\3\1\0"+ - "\10\3\1\201\5\3\27\0\1\3\4\0\10\3\1\0"+ - "\2\3\1\202\5\3\2\0\3\3\1\0\4\3\1\203"+ - "\11\3\27\0\1\3\4\0\10\3\1\0\1\3\1\204"+ - "\6\3\2\0\3\3\1\0\16\3\27\0\1\3\4\0"+ - "\10\3\1\0\7\3\1\205\2\0\3\3\1\0\16\3"+ - "\27\0\1\206\4\0\10\3\1\0\10\3\2\0\3\3"+ - "\1\0\16\3\27\0\1\3\4\0\10\3\1\0\1\3"+ - "\1\207\6\3\2\0\3\3\1\0\16\3\27\0\1\3"+ - "\4\0\10\3\1\0\6\3\1\210\1\3\2\0\3\3"+ - "\1\0\16\3\27\0\1\3\4\0\10\3\1\0\10\3"+ - "\2\0\3\3\1\0\3\3\1\211\12\3\27\0\1\3"+ - "\4\0\10\3\1\0\2\3\1\212\5\3\2\0\3\3"+ - "\1\0\16\3\27\0\1\3\4\0\10\3\1\0\10\3"+ - "\2\0\1\213\2\3\1\0\16\3\27\0\1\3\4\0"+ - "\10\3\1\0\7\3\1\214\2\0\3\3\1\0\16\3"+ - "\27\0\1\3\4\0\10\3\1\0\7\3\1\215\2\0"+ - "\3\3\1\0\16\3\27\0\1\3\4\0\10\3\1\0"+ - "\10\3\2\0\1\216\2\3\1\0\16\3\27\0\1\3"+ - "\4\0\10\3\1\0\10\3\2\0\3\3\1\0\12\3"+ - "\1\217\3\3\27\0\1\3\4\0\10\3\1\0\2\3"+ - "\1\220\2\3\1\221\2\3\2\0\3\3\1\0\16\3"+ - "\27\0\1\3\4\0\10\3\1\0\10\3\2\0\3\3"+ - "\1\0\3\3\1\222\12\3\27\0\1\3\4\0\10\3"+ - "\1\0\10\3\2\0\1\223\2\3\1\0\16\3\27\0"+ - "\1\3\4\0\10\3\1\0\10\3\2\0\3\3\1\0"+ - "\4\3\1\224\11\3\25\0\30\120\1\225\51\120\1\116"+ - "\1\226\7\120\1\227\3\120\1\230\2\120\2\116\1\120"+ - "\1\116\3\120\1\231\3\116\1\227\74\120\1\121\50\120"+ - "\1\123\1\22\1\232\7\123\1\22\3\123\1\22\2\123"+ - "\2\22\1\123\1\22\3\123\1\22\1\233\3\22\75\123"+ - "\1\234\47\123\2\0\1\3\4\0\10\3\1\0\6\3"+ - "\1\235\1\3\2\0\3\3\1\0\16\3\27\0\1\3"+ - "\4\0\10\3\1\0\10\3\2\0\3\3\1\0\14\3"+ - "\1\236\1\3\27\0\1\3\4\0\10\3\1\0\1\3"+ - "\1\237\6\3\2\0\3\3\1\0\16\3\27\0\1\3"+ - "\4\0\10\3\1\0\3\3\1\240\4\3\2\0\3\3"+ - "\1\0\16\3\27\0\1\3\4\0\10\3\1\0\10\3"+ - "\2\0\3\3\1\0\3\3\1\241\12\3\27\0\1\3"+ - "\4\0\10\3\1\0\1\3\1\242\6\3\2\0\3\3"+ - "\1\0\16\3\27\0\1\3\4\0\10\3\1\0\1\3"+ - "\1\243\5\3\1\244\2\0\3\3\1\0\16\3\27\0"+ - "\1\3\4\0\10\3\1\0\5\3\1\245\2\3\2\0"+ - "\3\3\1\0\16\3\27\0\1\3\4\0\10\3\1\0"+ - "\5\3\1\246\2\3\2\0\3\3\1\0\16\3\27\0"+ - "\1\3\4\0\10\3\1\0\10\3\2\0\1\247\2\3"+ - "\1\0\16\3\27\0\1\3\4\0\10\3\1\0\1\3"+ - "\1\250\5\3\1\251\2\0\3\3\1\0\16\3\27\0"+ - "\1\3\4\0\10\3\1\0\10\3\2\0\3\3\1\0"+ - "\12\3\1\252\3\3\27\0\1\3\4\0\10\3\1\0"+ - "\4\3\1\253\3\3\2\0\3\3\1\0\16\3\27\0"+ - "\1\254\4\0\10\3\1\0\10\3\2\0\3\3\1\0"+ - "\16\3\27\0\1\3\4\0\10\3\1\0\1\3\1\255"+ - "\6\3\2\0\3\3\1\0\16\3\27\0\1\3\4\0"+ - "\10\3\1\0\10\3\2\0\1\3\1\256\1\3\1\0"+ - "\16\3\27\0\1\3\4\0\10\3\1\0\10\3\2\0"+ - "\3\3\1\0\3\3\1\257\1\260\11\3\27\0\1\3"+ - "\4\0\10\3\1\0\10\3\2\0\3\3\1\0\1\261"+ - "\15\3\27\0\1\3\4\0\10\3\1\0\6\3\1\262"+ - "\1\3\2\0\3\3\1\0\4\3\1\263\11\3\27\0"+ - "\1\3\4\0\10\3\1\0\10\3\2\0\3\3\1\0"+ - "\4\3\1\264\11\3\111\0\1\265\1\266\77\0\1\267"+ - "\14\0\6\172\1\270\72\172\5\271\1\272\1\173\72\271"+ - "\11\0\1\66\2\174\1\0\2\174\1\0\1\174\2\0"+ - "\3\174\1\66\4\0\2\174\1\0\1\174\4\0\1\174"+ - "\47\0\2\175\2\0\1\175\1\0\1\273\3\0\1\273"+ - "\7\0\1\175\46\0\1\3\4\0\10\3\1\0\3\3"+ - "\1\274\4\3\2\0\3\3\1\0\16\3\27\0\1\3"+ - "\4\0\10\3\1\0\10\3\2\0\1\275\2\3\1\0"+ - "\16\3\27\0\1\3\4\0\10\3\1\0\10\3\2\0"+ - "\3\3\1\0\3\3\1\276\12\3\27\0\1\3\4\0"+ - "\10\3\1\0\7\3\1\277\2\0\3\3\1\0\16\3"+ - "\27\0\1\300\4\0\10\3\1\0\10\3\2\0\3\3"+ - "\1\0\16\3\27\0\1\3\4\0\10\3\1\0\3\3"+ - "\1\301\4\3\2\0\3\3\1\0\16\3\27\0\1\3"+ - "\4\0\10\3\1\0\10\3\2\0\3\3\1\0\6\3"+ - "\1\302\7\3\27\0\1\3\4\0\10\3\1\0\3\3"+ - "\1\303\4\3\2\0\3\3\1\0\16\3\27\0\1\3"+ - "\4\0\10\3\1\0\7\3\1\177\2\0\3\3\1\0"+ - "\16\3\27\0\1\3\4\0\10\3\1\0\5\3\1\304"+ - "\2\3\2\0\3\3\1\0\16\3\27\0\1\3\4\0"+ - "\10\3\1\0\5\3\1\305\2\3\2\0\3\3\1\0"+ - "\16\3\27\0\1\3\4\0\10\3\1\0\3\3\1\306"+ - "\4\3\2\0\3\3\1\0\16\3\27\0\1\3\4\0"+ - "\10\3\1\0\1\3\1\307\6\3\2\0\3\3\1\0"+ - "\16\3\27\0\1\3\4\0\10\3\1\0\10\3\2\0"+ - "\3\3\1\0\11\3\1\310\4\3\27\0\1\3\4\0"+ - "\10\3\1\0\3\3\1\311\4\3\2\0\3\3\1\0"+ - "\16\3\27\0\1\3\4\0\10\3\1\0\10\3\2\0"+ - "\3\3\1\0\4\3\1\312\11\3\27\0\1\3\4\0"+ - "\10\3\1\0\1\3\1\313\6\3\2\0\3\3\1\0"+ - "\16\3\27\0\1\3\4\0\10\3\1\0\2\3\1\314"+ - "\5\3\2\0\3\3\1\0\16\3\27\0\1\3\4\0"+ - "\10\3\1\0\10\3\2\0\3\3\1\0\1\315\15\3"+ - "\27\0\1\3\4\0\10\3\1\0\1\3\1\316\6\3"+ - "\2\0\3\3\1\0\16\3\25\0\2\120\1\226\7\120"+ - "\2\317\1\120\2\317\1\120\1\317\2\120\3\317\2\120"+ - "\1\121\2\120\2\317\1\120\1\317\4\120\1\317\47\120"+ - "\1\230\3\120\1\230\11\120\1\225\3\120\1\230\56\120"+ - "\1\116\3\120\1\116\11\120\1\225\3\120\1\116\44\120"+ - "\30\0\1\225\50\0\2\123\1\232\7\123\2\320\1\123"+ - "\2\320\1\123\1\320\2\123\3\320\3\123\1\234\1\123"+ - "\2\320\1\123\1\320\4\123\1\320\35\123\1\321\1\322"+ - "\1\321\1\0\25\321\1\124\47\321\2\0\1\3\4\0"+ - "\10\3\1\0\6\3\1\323\1\3\2\0\3\3\1\0"+ - "\16\3\27\0\1\3\4\0\10\3\1\0\10\3\2\0"+ - "\3\3\1\0\4\3\1\324\11\3\27\0\1\3\4\0"+ - "\10\3\1\0\5\3\1\325\2\3\2\0\3\3\1\0"+ - "\16\3\27\0\1\3\4\0\10\3\1\0\6\3\1\326"+ - "\1\3\2\0\3\3\1\0\16\3\27\0\1\3\4\0"+ - "\10\3\1\0\3\3\1\327\4\3\2\0\3\3\1\0"+ - "\16\3\27\0\1\3\4\0\10\3\1\0\10\3\2\0"+ - "\3\3\1\0\1\330\15\3\27\0\1\3\4\0\10\3"+ - "\1\0\3\3\1\331\4\3\2\0\3\3\1\0\16\3"+ - "\27\0\1\3\4\0\10\3\1\0\7\3\1\332\2\0"+ - "\3\3\1\0\16\3\27\0\1\3\4\0\10\3\1\0"+ - "\2\3\1\333\5\3\2\0\3\3\1\0\16\3\27\0"+ - "\1\3\4\0\10\3\1\0\1\3\1\334\5\3\1\335"+ - "\2\0\3\3\1\0\16\3\27\0\1\3\4\0\10\3"+ - "\1\0\3\3\1\336\4\3\2\0\3\3\1\0\16\3"+ - "\27\0\1\3\4\0\10\3\1\0\1\3\1\337\6\3"+ - "\2\0\3\3\1\0\16\3\27\0\1\3\4\0\10\3"+ - "\1\0\6\3\1\340\1\3\2\0\3\3\1\0\3\3"+ - "\1\341\12\3\27\0\1\3\4\0\10\3\1\0\5\3"+ - "\1\342\2\3\2\0\3\3\1\0\16\3\27\0\1\3"+ - "\4\0\10\3\1\0\10\3\2\0\1\3\1\343\1\3"+ - "\1\0\16\3\27\0\1\3\4\0\10\3\1\0\10\3"+ - "\2\0\3\3\1\0\3\3\1\344\12\3\27\0\1\3"+ - "\4\0\10\3\1\0\6\3\1\345\1\3\2\0\3\3"+ - "\1\0\16\3\27\0\1\3\4\0\10\3\1\0\1\3"+ - "\1\346\6\3\2\0\3\3\1\0\16\3\27\0\1\3"+ - "\4\0\10\3\1\0\10\3\2\0\3\3\1\0\13\3"+ - "\1\347\2\3\27\0\1\3\4\0\10\3\1\0\10\3"+ - "\2\0\3\3\1\0\1\3\1\350\14\3\27\0\1\3"+ - "\4\0\10\3\1\0\5\3\1\351\2\3\2\0\3\3"+ - "\1\0\16\3\27\0\1\3\4\0\10\3\1\0\10\3"+ - "\2\0\3\3\1\0\5\3\1\352\10\3\27\0\1\3"+ - "\4\0\10\3\1\0\6\3\1\353\1\3\2\0\3\3"+ - "\1\0\16\3\111\0\1\354\14\0\5\172\1\272\1\270"+ - "\72\172\6\271\1\355\72\271\2\0\1\3\4\0\10\3"+ - "\1\0\7\3\1\356\2\0\3\3\1\0\16\3\27\0"+ - "\1\3\4\0\10\3\1\0\10\3\2\0\3\3\1\0"+ - "\14\3\1\357\1\3\27\0\1\3\4\0\10\3\1\0"+ - "\2\3\1\360\5\3\2\0\3\3\1\0\16\3\27\0"+ - "\1\3\4\0\10\3\1\0\10\3\2\0\1\361\2\3"+ - "\1\0\16\3\27\0\1\3\4\0\10\3\1\0\1\3"+ - "\1\362\6\3\2\0\3\3\1\0\16\3\27\0\1\3"+ - "\4\0\10\3\1\0\6\3\1\363\1\3\2\0\3\3"+ - "\1\0\16\3\27\0\1\3\4\0\10\3\1\0\2\3"+ - "\1\364\5\3\2\0\3\3\1\0\16\3\27\0\1\3"+ - "\4\0\10\3\1\0\2\3\1\365\5\3\2\0\3\3"+ - "\1\0\16\3\27\0\1\3\4\0\10\3\1\0\2\3"+ - "\1\366\5\3\2\0\3\3\1\0\16\3\27\0\1\3"+ - "\4\0\10\3\1\0\10\3\2\0\3\3\1\0\1\367"+ - "\15\3\27\0\1\3\4\0\10\3\1\0\10\3\2\0"+ - "\3\3\1\0\4\3\1\370\11\3\27\0\1\3\4\0"+ - "\10\3\1\0\1\3\1\371\6\3\2\0\3\3\1\0"+ - "\16\3\27\0\1\3\4\0\10\3\1\0\10\3\2\0"+ - "\3\3\1\0\2\3\1\372\13\3\27\0\1\3\4\0"+ - "\10\3\1\0\10\3\2\0\3\3\1\0\1\373\15\3"+ - "\25\0\12\120\2\374\1\120\2\374\1\120\1\374\2\120"+ - "\3\374\2\120\1\121\2\120\2\374\1\120\1\374\4\120"+ - "\1\374\35\120\12\123\2\375\1\123\2\375\1\123\1\375"+ - "\2\123\3\375\3\123\1\234\1\123\2\375\1\123\1\375"+ - "\4\123\1\375\35\123\1\0\1\321\1\376\7\0\1\321"+ - "\3\0\1\321\2\0\2\321\1\0\1\321\3\0\5\321"+ - "\46\0\1\3\4\0\10\3\1\0\10\3\2\0\3\3"+ - "\1\0\13\3\1\377\2\3\27\0\1\3\4\0\10\3"+ - "\1\0\10\3\2\0\3\3\1\0\1\3\1\u0100\14\3"+ - "\27\0\1\3\4\0\10\3\1\0\3\3\1\u0101\4\3"+ - "\2\0\3\3\1\0\16\3\27\0\1\3\4\0\10\3"+ - "\1\0\10\3\2\0\3\3\1\0\2\3\1\u0102\13\3"+ - "\27\0\1\3\4\0\10\3\1\0\7\3\1\u0103\2\0"+ - "\3\3\1\0\16\3\27\0\1\3\4\0\10\3\1\0"+ - "\10\3\2\0\3\3\1\0\4\3\1\u0104\11\3\27\0"+ - "\1\3\4\0\10\3\1\0\1\3\1\u0105\6\3\2\0"+ - "\3\3\1\0\16\3\27\0\1\3\4\0\10\3\1\0"+ - "\2\3\1\u0106\5\3\2\0\3\3\1\0\16\3\27\0"+ - "\1\3\4\0\10\3\1\0\5\3\1\u0107\2\3\2\0"+ - "\3\3\1\0\16\3\27\0\1\3\4\0\10\3\1\0"+ - "\3\3\1\u0108\4\3\2\0\3\3\1\0\16\3\27\0"+ - "\1\3\4\0\10\3\1\0\2\3\1\u0109\5\3\2\0"+ - "\3\3\1\0\16\3\27\0\1\u010a\4\0\10\3\1\0"+ - "\10\3\2\0\3\3\1\0\16\3\27\0\1\3\4\0"+ - "\10\3\1\0\6\3\1\u010b\1\3\2\0\3\3\1\0"+ - "\16\3\27\0\1\3\4\0\10\3\1\0\10\3\2\0"+ - "\3\3\1\0\4\3\1\u010c\11\3\27\0\1\3\4\0"+ - "\10\3\1\0\3\3\1\u010d\4\3\2\0\3\3\1\0"+ - "\16\3\27\0\1\3\4\0\10\3\1\0\5\3\1\u010e"+ - "\2\3\2\0\3\3\1\0\16\3\27\0\1\3\4\0"+ - "\10\3\1\0\5\3\1\u010f\2\3\2\0\3\3\1\0"+ - "\16\3\27\0\1\3\4\0\10\3\1\0\1\3\1\u0110"+ - "\6\3\2\0\3\3\1\0\16\3\27\0\1\3\4\0"+ - "\10\3\1\0\3\3\1\u0111\4\3\2\0\3\3\1\0"+ - "\16\3\25\0\5\271\1\u0112\1\355\72\271\2\0\1\3"+ - "\4\0\10\3\1\0\10\3\2\0\3\3\1\0\4\3"+ - "\1\u0113\11\3\27\0\1\3\4\0\10\3\1\0\7\3"+ - "\1\u0114\2\0\3\3\1\0\16\3\27\0\1\3\4\0"+ - "\10\3\1\0\10\3\2\0\1\u0115\2\3\1\0\16\3"+ - "\27\0\1\3\4\0\10\3\1\0\10\3\2\0\3\3"+ - "\1\0\5\3\1\u0116\10\3\27\0\1\3\4\0\10\3"+ - "\1\0\6\3\1\u0117\1\3\2\0\3\3\1\0\16\3"+ - "\27\0\1\3\4\0\10\3\1\0\1\3\1\u0118\6\3"+ - "\2\0\3\3\1\0\16\3\27\0\1\3\4\0\10\3"+ - "\1\0\5\3\1\u0119\2\3\2\0\3\3\1\0\16\3"+ - "\27\0\1\3\4\0\10\3\1\0\1\3\1\u011a\6\3"+ - "\2\0\3\3\1\0\16\3\27\0\1\3\4\0\10\3"+ - "\1\0\10\3\2\0\3\3\1\0\1\u011b\15\3\27\0"+ - "\1\3\4\0\10\3\1\0\2\3\1\u011c\5\3\2\0"+ - "\3\3\1\0\16\3\27\0\1\3\4\0\10\3\1\0"+ - "\10\3\2\0\3\3\1\0\2\3\1\u011d\13\3\25\0"+ - "\12\120\2\u011e\1\120\2\u011e\1\120\1\u011e\2\120\3\u011e"+ - "\2\120\1\121\2\120\2\u011e\1\120\1\u011e\4\120\1\u011e"+ - "\35\120\12\123\2\u011f\1\123\2\u011f\1\123\1\u011f\2\123"+ - "\3\u011f\3\123\1\234\1\123\2\u011f\1\123\1\u011f\4\123"+ - "\1\u011f\35\123\2\0\1\376\7\0\2\u0120\1\0\2\u0120"+ - "\1\0\1\u0120\2\0\3\u0120\5\0\2\u0120\1\0\1\u0120"+ - "\4\0\1\u0120\37\0\1\3\4\0\10\3\1\0\3\3"+ - "\1\u0121\4\3\2\0\3\3\1\0\16\3\27\0\1\3"+ - "\4\0\10\3\1\0\5\3\1\u0122\2\3\2\0\3\3"+ - "\1\0\16\3\27\0\1\3\4\0\10\3\1\0\10\3"+ - "\2\0\1\u0123\2\3\1\0\16\3\27\0\1\3\4\0"+ - "\10\3\1\0\4\3\1\u0124\3\3\2\0\3\3\1\0"+ - "\16\3\27\0\1\3\4\0\10\3\1\0\10\3\2\0"+ - "\1\u0125\2\3\1\0\16\3\27\0\1\3\4\0\10\3"+ - "\1\0\10\3\2\0\3\3\1\0\6\3\1\u0126\7\3"+ - "\27\0\1\3\4\0\10\3\1\0\1\3\1\u0127\6\3"+ - "\2\0\3\3\1\0\16\3\27\0\1\3\4\0\10\3"+ - "\1\0\6\3\1\u0128\1\3\2\0\3\3\1\0\16\3"+ - "\27\0\1\3\4\0\10\3\1\0\3\3\1\u0129\4\3"+ - "\2\0\3\3\1\0\16\3\27\0\1\3\4\0\10\3"+ - "\1\0\10\3\2\0\3\3\1\0\1\u012a\15\3\27\0"+ - "\1\3\4\0\10\3\1\0\10\3\2\0\3\3\1\0"+ - "\1\u012b\15\3\27\0\1\3\4\0\10\3\1\0\1\3"+ - "\1\u012c\6\3\2\0\3\3\1\0\16\3\27\0\1\3"+ - "\4\0\10\3\1\0\10\3\2\0\3\3\1\0\11\3"+ - "\1\u012d\4\3\27\0\1\3\4\0\10\3\1\0\10\3"+ - "\2\0\3\3\1\0\4\3\1\u012e\11\3\27\0\1\3"+ - "\4\0\10\3\1\0\3\3\1\u012f\4\3\2\0\3\3"+ - "\1\0\16\3\27\0\1\3\4\0\10\3\1\0\7\3"+ - "\1\u0130\2\0\3\3\1\0\16\3\27\0\1\3\4\0"+ - "\10\3\1\0\10\3\2\0\3\3\1\0\10\3\1\u0131"+ - "\5\3\27\0\1\3\4\0\10\3\1\0\10\3\2\0"+ - "\3\3\1\0\1\u0132\15\3\27\0\1\3\4\0\10\3"+ - "\1\0\4\3\1\u0133\3\3\2\0\3\3\1\0\16\3"+ - "\27\0\1\3\4\0\10\3\1\0\10\3\2\0\3\3"+ - "\1\0\3\3\1\u0134\12\3\25\0\12\120\2\116\1\120"+ - "\2\116\1\120\1\116\2\120\3\116\2\120\1\121\2\120"+ - "\2\116\1\120\1\116\4\120\1\116\35\120\12\123\2\22"+ - "\1\123\2\22\1\123\1\22\2\123\3\22\3\123\1\234"+ - "\1\123\2\22\1\123\1\22\4\123\1\22\35\123\12\0"+ - "\2\u0135\1\0\2\u0135\1\0\1\u0135\2\0\3\u0135\5\0"+ - "\2\u0135\1\0\1\u0135\4\0\1\u0135\37\0\1\3\4\0"+ - "\10\3\1\0\10\3\2\0\1\u0136\2\3\1\0\16\3"+ - "\27\0\1\u0137\4\0\10\3\1\0\10\3\2\0\3\3"+ - "\1\0\16\3\27\0\1\3\4\0\10\3\1\0\5\3"+ - "\1\u0138\2\3\2\0\3\3\1\0\16\3\27\0\1\3"+ - "\4\0\10\3\1\0\10\3\2\0\3\3\1\0\1\u0139"+ - "\15\3\27\0\1\3\4\0\10\3\1\0\3\3\1\u013a"+ - "\4\3\2\0\3\3\1\0\16\3\27\0\1\3\4\0"+ - "\10\3\1\0\1\3\1\u013b\6\3\2\0\3\3\1\0"+ - "\16\3\27\0\1\3\4\0\10\3\1\0\1\3\1\u013c"+ - "\6\3\2\0\3\3\1\0\16\3\27\0\1\3\4\0"+ - "\10\3\1\0\3\3\1\u013d\4\3\2\0\3\3\1\0"+ - "\16\3\27\0\1\3\4\0\10\3\1\0\3\3\1\u013e"+ - "\4\3\2\0\3\3\1\0\16\3\27\0\1\3\4\0"+ - "\10\3\1\0\6\3\1\u013f\1\3\2\0\3\3\1\0"+ - "\16\3\27\0\1\3\4\0\10\3\1\0\10\3\2\0"+ - "\1\u0140\2\3\1\0\16\3\27\0\1\3\4\0\10\3"+ - "\1\0\1\3\1\u0141\6\3\2\0\3\3\1\0\16\3"+ - "\27\0\1\3\4\0\10\3\1\0\10\3\2\0\3\3"+ - "\1\0\12\3\1\u0142\3\3\27\0\1\3\4\0\10\3"+ - "\1\0\10\3\2\0\1\u0143\2\3\1\0\16\3\37\0"+ - "\2\u0144\1\0\2\u0144\1\0\1\u0144\2\0\3\u0144\5\0"+ - "\2\u0144\1\0\1\u0144\4\0\1\u0144\37\0\1\3\4\0"+ - "\10\3\1\0\3\3\1\u0145\4\3\2\0\3\3\1\0"+ - "\16\3\27\0\1\3\4\0\10\3\1\0\10\3\2\0"+ - "\3\3\1\0\1\u0146\15\3\27\0\1\3\4\0\10\3"+ - "\1\0\3\3\1\u0147\4\3\2\0\3\3\1\0\16\3"+ - "\27\0\1\3\4\0\10\3\1\0\10\3\2\0\1\u0148"+ - "\2\3\1\0\16\3\27\0\1\3\4\0\10\3\1\0"+ - "\3\3\1\u0149\4\3\2\0\3\3\1\0\16\3\27\0"+ - "\1\3\4\0\10\3\1\0\3\3\1\u014a\4\3\2\0"+ - "\3\3\1\0\16\3\27\0\1\3\4\0\10\3\1\0"+ - "\1\3\1\u014b\6\3\2\0\3\3\1\0\16\3\27\0"+ - "\1\3\4\0\10\3\1\0\10\3\2\0\3\3\1\0"+ - "\4\3\1\u014c\11\3\37\0\2\321\1\0\2\321\1\0"+ - "\1\321\2\0\3\321\5\0\2\321\1\0\1\321\4\0"+ - "\1\321\37\0\1\3\4\0\10\3\1\0\3\3\1\u014d"+ - "\4\3\2\0\3\3\1\0\16\3\27\0\1\3\4\0"+ - "\10\3\1\0\10\3\2\0\3\3\1\0\3\3\1\u014e"+ - "\12\3\27\0\1\3\4\0\10\3\1\0\1\3\1\u014f"+ - "\6\3\2\0\3\3\1\0\16\3\27\0\1\3\4\0"+ - "\10\3\1\0\10\3\2\0\3\3\1\0\5\3\1\u0150"+ - "\10\3\27\0\1\3\4\0\10\3\1\0\10\3\2\0"+ - "\3\3\1\0\15\3\1\u0151\27\0\1\3\4\0\10\3"+ - "\1\0\4\3\1\u0152\3\3\2\0\3\3\1\0\16\3"+ - "\27\0\1\3\4\0\10\3\1\0\7\3\1\u0153\2\0"+ - "\3\3\1\0\16\3\27\0\1\3\4\0\10\3\1\0"+ - "\3\3\1\u0154\4\3\2\0\3\3\1\0\16\3\27\0"+ - "\1\3\4\0\10\3\1\0\10\3\2\0\3\3\1\0"+ - "\5\3\1\u0155\10\3\25\0"; - - private static int [] zzUnpackTrans() { - int [] result = new int[16380]; - int offset = 0; - offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); - return result; - } - - private static int zzUnpackTrans(String packed, int offset, int [] result) { - int i = 0; /* index in packed string */ - int j = offset; /* index in unpacked array */ - int l = packed.length(); - while (i < l) { - int count = packed.charAt(i++); - int value = packed.charAt(i++); - value--; - do result[j++] = value; while (--count > 0); - } - return j; - } - - - /* error codes */ - private static final int ZZ_UNKNOWN_ERROR = 0; - private static final int ZZ_NO_MATCH = 1; - private static final int ZZ_PUSHBACK_2BIG = 2; - - /* error messages for the codes above */ - private static final String ZZ_ERROR_MSG[] = { - "Unkown internal scanner error", - "Error: could not match input", - "Error: pushback value was too large" - }; - - /** - * ZZ_ATTRIBUTE[aState] contains the attributes of state aState - */ - private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute(); - - private static final String ZZ_ATTRIBUTE_PACKED_0 = - "\1\0\1\11\22\1\1\11\7\1\10\11\4\1\3\11"+ - "\7\1\1\0\3\11\1\1\4\0\25\1\1\11\2\1"+ - "\1\11\25\1\2\11\1\1\1\11\1\1\13\11\2\0"+ - "\1\1\1\0\1\11\26\1\1\11\6\1\1\11\30\1"+ - "\1\11\1\1\1\11\2\0\2\11\25\1\2\0\31\1"+ - "\1\11\1\0\20\1\1\0\23\1\1\11\15\1\1\0"+ - "\24\1\1\0\16\1\1\0\21\1"; - - private static int [] zzUnpackAttribute() { - int [] result = new int[341]; - int offset = 0; - offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); - return result; - } - - private static int zzUnpackAttribute(String packed, int offset, int [] result) { - int i = 0; /* index in packed string */ - int j = offset; /* index in unpacked array */ - int l = packed.length(); - while (i < l) { - int count = packed.charAt(i++); - int value = packed.charAt(i++); - do result[j++] = value; while (--count > 0); - } - return j; - } - - /** the input device */ - private java.io.Reader zzReader; - - /** the current state of the DFA */ - private int zzState; - - /** the current lexical state */ - private int zzLexicalState = YYINITIAL; - - /** this buffer contains the current text to be matched and is - the source of the yytext() string */ - private char zzBuffer[] = new char[ZZ_BUFFERSIZE]; - - /** the textposition at the last accepting state */ - private int zzMarkedPos; - - /** the current text position in the buffer */ - private int zzCurrentPos; - - /** startRead marks the beginning of the yytext() string in the buffer */ - private int zzStartRead; - - /** endRead marks the last character in the buffer, that has been read - from input */ - private int zzEndRead; - - /** number of newlines encountered up to the start of the matched text */ - private int yyline; - - /** the number of characters up to the start of the matched text */ - private int yychar; - - /** - * the number of characters from the last newline up to the start of the - * matched text - */ - private int yycolumn; - - /** zzAtEOF == true <=> the scanner is at the EOF */ - private boolean zzAtEOF; - - /* user code: */ - - /** - * Whether comments should be returned as tokens. - */ - private boolean returnComments; - - /** - * Whether whitespace should be returned as tokens. - */ - private boolean returnWhitespace; - - /** - * Whether the last documentation comment parsed should be kept. - */ - private boolean keepLastDocComment; - - /** - * The last documentation comment parsed, if that feature is enabled. - */ - private String lastDocComment; - - - private Token createToken(int type) { - return createToken(type, false); - } - - - private Token createToken(int type, boolean invalid) { - return new TokenImpl(type, yytext(), yyline, yycolumn, yychar, invalid); - } - - - /** - * Returns the current column into the current line. - * - * @return The current column. - */ - public int getColumn() { - return yycolumn; - } - - - /** - * Returns the last documentation comment parsed, if this feature is - * enabled. The "last documentation comment" is cleared when this method - * returns. - * - * @return The last documentation comment parsed, or null - * if the feature is disabled. - * @see #setKeepLastDocComment(boolean) - */ - public String getLastDocComment() { - String comment = lastDocComment; - lastDocComment = null; - return comment; - } - - - /** - * Returns the current line into the document. - * - * @return The current line. - */ - public int getLine() { - return yyline; - } - - - /** - * Returns the current offset into the document. - * - * @return The offset. - */ - public int getOffset() { - return yychar; - } - - - /** - * Returns whether comments are returned as tokens. - * - * @return Whether comments are returned as tokens. - * @see #getReturnWhitespace() - */ - public boolean getReturnComments() { - return returnComments; - } - - - /** - * Returns whether whitespace is returned as tokens. - * - * @return Whether whitespace is returned as tokens. - * @see #getReturnComments() - */ - public boolean getReturnWhitespace() { - return returnWhitespace; - } - - - /** - * Sets whether the last documentation comment should be kept. - * - * @param keep Whether to keep the last documentation comment. - * @see #getLastDocComment() - */ - public void setKeepLastDocComment(boolean keep) { - keepLastDocComment = keep; - } - - - /** - * Sets whether comments are returned as tokens. - * - * @param returnComments Whether comments should be returned as tokens. - * @see #getReturnComments() - * @see #setReturnWhitespace(boolean) - */ - public void setReturnComments(boolean returnComments) { - this.returnComments = returnComments; - } - - - /** - * Sets whether whitespace is returned as tokens. - * - * @param returnWhitespace Whether whitespace should be returned as tokens. - * @see #getReturnWhitespace() - * @see #setReturnComments(boolean) - */ - public void setReturnWhitespace(boolean returnWhitespace) { - this.returnWhitespace = returnWhitespace; - } - - - - - /** - * Creates a new scanner - * There is also a java.io.InputStream version of this constructor. - * - * @param in the java.io.Reader to read input from. - */ - SourceCodeScanner(java.io.Reader in) { - this.zzReader = in; - } - - /** - * Creates a new scanner. - * There is also java.io.Reader version of this constructor. - * - * @param in the java.io.Inputstream to read input from. - */ - SourceCodeScanner(java.io.InputStream in) { - this(new java.io.InputStreamReader(in)); - } - - /** - * Unpacks the compressed character translation table. - * - * @param packed the packed character translation table - * @return the unpacked character translation table - */ - private static char [] zzUnpackCMap(String packed) { - char [] map = new char[0x10000]; - int i = 0; /* index in packed string */ - int j = 0; /* index in unpacked array */ - while (i < 1776) { - int count = packed.charAt(i++); - char value = packed.charAt(i++); - do map[j++] = value; while (--count > 0); - } - return map; - } - - - /** - * Refills the input buffer. - * - * @return false, iff there was new input. - * - * @exception java.io.IOException if any I/O-Error occurs - */ - private boolean zzRefill() throws java.io.IOException { - - /* first: make room (if you can) */ - if (zzStartRead > 0) { - System.arraycopy(zzBuffer, zzStartRead, - zzBuffer, 0, - zzEndRead-zzStartRead); - - /* translate stored positions */ - zzEndRead-= zzStartRead; - zzCurrentPos-= zzStartRead; - zzMarkedPos-= zzStartRead; - zzStartRead = 0; - } - - /* is the buffer big enough? */ - if (zzCurrentPos >= zzBuffer.length) { - /* if not: blow it up */ - char newBuffer[] = new char[zzCurrentPos*2]; - System.arraycopy(zzBuffer, 0, newBuffer, 0, zzBuffer.length); - zzBuffer = newBuffer; - } - - /* finally: fill the buffer with new input */ - int numRead = zzReader.read(zzBuffer, zzEndRead, - zzBuffer.length-zzEndRead); - - if (numRead < 0) { - return true; - } - else { - zzEndRead+= numRead; - return false; - } - } - - - /** - * Closes the input stream. - */ - public final void yyclose() throws java.io.IOException { - zzAtEOF = true; /* indicate end of file */ - zzEndRead = zzStartRead; /* invalidate buffer */ - - if (zzReader != null) - zzReader.close(); - } - - - /** - * Resets the scanner to read from a new input stream. - * Does not close the old reader. - * - * All internal variables are reset, the old input stream - * cannot be reused (internal buffer is discarded and lost). - * Lexical state is set to ZZ_INITIAL. - * - * @param reader the new input stream - */ - public final void yyreset(java.io.Reader reader) { - zzReader = reader; - zzAtEOF = false; - zzEndRead = zzStartRead = 0; - zzCurrentPos = zzMarkedPos = 0; - yyline = yychar = yycolumn = 0; - zzLexicalState = YYINITIAL; - } - - - /** - * Returns the current lexical state. - */ - public final int yystate() { - return zzLexicalState; - } - - - /** - * Enters a new lexical state - * - * @param newState the new lexical state - */ - public final void yybegin(int newState) { - zzLexicalState = newState; - } - - - /** - * Returns the text matched by the current regular expression. - */ - public final String yytext() { - return new String( zzBuffer, zzStartRead, zzMarkedPos-zzStartRead ); - } - - - /** - * Returns the character at position pos from the - * matched text. - * - * It is equivalent to yytext().charAt(pos), but faster - * - * @param pos the position of the character to fetch. - * A value from 0 to yylength()-1. - * - * @return the character at position pos - */ - public final char yycharat(int pos) { - return zzBuffer[zzStartRead+pos]; - } - - - /** - * Returns the length of the matched text region. - */ - public final int yylength() { - return zzMarkedPos-zzStartRead; - } - - - /** - * Reports an error that occured while scanning. - * - * In a wellformed scanner (no or only correct usage of - * yypushback(int) and a match-all fallback rule) this method - * will only be called with things that "Can't Possibly Happen". - * If this method is called, something is seriously wrong - * (e.g. a JFlex bug producing a faulty scanner etc.). - * - * Usual syntax/scanner level error handling should be done - * in error fallback rules. - * - * @param errorCode the code of the errormessage to display - */ - private void zzScanError(int errorCode) { - String message; - try { - message = ZZ_ERROR_MSG[errorCode]; - } - catch (ArrayIndexOutOfBoundsException e) { - message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR]; - } - - throw new Error(message); - } - - - /** - * Pushes the specified amount of characters back into the input stream. - * - * They will be read again by then next call of the scanning method - * - * @param number the number of characters to be read again. - * This number must not be greater than yylength()! - */ - public void yypushback(int number) { - if ( number > yylength() ) - zzScanError(ZZ_PUSHBACK_2BIG); - - zzMarkedPos -= number; - } - - - /** - * Resumes scanning until the next regular expression is matched, - * the end of input is encountered or an I/O-Error occurs. - * - * @return the next token - * @exception java.io.IOException if any I/O-Error occurs - */ - public org.fife.rsta.ac.bsh.rjc.lexer.Token yylex() throws java.io.IOException { - int zzInput; - int zzAction; - - // cached fields: - int zzCurrentPosL; - int zzMarkedPosL; - int zzEndReadL = zzEndRead; - char [] zzBufferL = zzBuffer; - char [] zzCMapL = ZZ_CMAP; - - int [] zzTransL = ZZ_TRANS; - int [] zzRowMapL = ZZ_ROWMAP; - int [] zzAttrL = ZZ_ATTRIBUTE; - - while (true) { - zzMarkedPosL = zzMarkedPos; - - yychar+= zzMarkedPosL-zzStartRead; - - boolean zzR = false; - for (zzCurrentPosL = zzStartRead; zzCurrentPosL < zzMarkedPosL; - zzCurrentPosL++) { - switch (zzBufferL[zzCurrentPosL]) { - case '\u000B': - case '\u000C': - case '\u0085': - case '\u2028': - case '\u2029': - yyline++; - yycolumn = 0; - zzR = false; - break; - case '\r': - yyline++; - yycolumn = 0; - zzR = true; - break; - case '\n': - if (zzR) - zzR = false; - else { - yyline++; - yycolumn = 0; - } - break; - default: - zzR = false; - yycolumn++; - } - } - - if (zzR) { - // peek one character ahead if it is \n (if we have counted one line too much) - boolean zzPeek; - if (zzMarkedPosL < zzEndReadL) - zzPeek = zzBufferL[zzMarkedPosL] == '\n'; - else if (zzAtEOF) - zzPeek = false; - else { - boolean eof = zzRefill(); - zzEndReadL = zzEndRead; - zzMarkedPosL = zzMarkedPos; - zzBufferL = zzBuffer; - if (eof) - zzPeek = false; - else - zzPeek = zzBufferL[zzMarkedPosL] == '\n'; - } - if (zzPeek) yyline--; - } - zzAction = -1; - - zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL; - - zzState = zzLexicalState; - - - zzForAction: { - while (true) { - - if (zzCurrentPosL < zzEndReadL) - zzInput = zzBufferL[zzCurrentPosL++]; - else if (zzAtEOF) { - zzInput = YYEOF; - break zzForAction; - } - else { - // store back cached positions - zzCurrentPos = zzCurrentPosL; - zzMarkedPos = zzMarkedPosL; - boolean eof = zzRefill(); - // get translated positions and possibly new buffer - zzCurrentPosL = zzCurrentPos; - zzMarkedPosL = zzMarkedPos; - zzBufferL = zzBuffer; - zzEndReadL = zzEndRead; - if (eof) { - zzInput = YYEOF; - break zzForAction; - } - else { - zzInput = zzBufferL[zzCurrentPosL++]; - } - } - int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMapL[zzInput] ]; - if (zzNext == -1) break zzForAction; - zzState = zzNext; - - int zzAttributes = zzAttrL[zzState]; - if ( (zzAttributes & 1) == 1 ) { - zzAction = zzState; - zzMarkedPosL = zzCurrentPosL; - if ( (zzAttributes & 8) == 8 ) break zzForAction; - } - - } - } - - // store back cached position - zzMarkedPos = zzMarkedPosL; - - switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) { - case 87: - { return createToken(KEYWORD_THROWS); - } - case 112: break; - case 11: - { return createToken(SEPARATOR_LPAREN); - } - case 113: break; - case 105: - { return createToken(KEYWORD_VOLATILE); - } - case 114: break; - case 95: - { return createToken(KEYWORD_PUBLIC); - } - case 115: break; - case 5: - { return createToken(OPERATOR_TIMES); - } - case 116: break; - case 71: - { return createToken(KEYWORD_CASE); - } - case 117: break; - case 34: - { return createToken(OPERATOR_TIMES_EQUALS); - } - case 118: break; - case 89: - { return createToken(KEYWORD_ASSERT); - } - case 119: break; - case 51: - { return createToken(OPERATOR_DECREMENT); - } - case 120: break; - case 15: - { return createToken(SEPARATOR_LBRACKET); - } - case 121: break; - case 104: - { return createToken(KEYWORD_CONTINUE); - } - case 122: break; - case 80: - { return createToken(KEYWORD_SHORT); - } - case 123: break; - case 26: - { return createToken(OPERATOR_BITWISE_AND); - } - case 124: break; - case 31: - { return createToken(OPERATOR_MOD); - } - case 125: break; - case 74: - { return createToken(KEYWORD_VOID); - } - case 126: break; - case 62: - { return createToken(OPERATOR_LSHIFT_EQUALS); - } - case 127: break; - case 38: - { return createToken(OPERATOR_EQUALS_EQUALS); - } - case 128: break; - case 69: - { return createToken(LITERAL_NULL); - } - case 129: break; - case 43: - { return createToken(OPERATOR_NE); - } - case 130: break; - case 28: - { return createToken(OPERATOR_PLUS); - } - case 131: break; - case 23: - { return createToken(OPERATOR_BITWISE_NOT); - } - case 132: break; - case 7: - { return createToken(SEPARATOR_DOT); - } - case 133: break; - case 102: - { return createToken(KEYWORD_ABSTRACT); - } - case 134: break; - case 92: - { return createToken(KEYWORD_NATIVE); - } - case 135: break; - case 35: - { return createToken(LITERAL_STRING); - } - case 136: break; - case 46: - { return createToken(OPERATOR_BITWISE_OR_EQUALS); - } - case 137: break; - case 60: - { return createToken(OPERATOR_RSHIFT_EQUALS); - } - case 138: break; - case 91: - { return createToken(KEYWORD_SWITCH); - } - case 139: break; - case 76: - { return createToken(KEYWORD_THROW); - } - case 140: break; - case 75: - { return createToken(OPERATOR_RSHIFT2_EQUALS); - } - case 141: break; - case 66: - { return createToken(KEYWORD_ELSE); - } - case 142: break; - case 3: - { if (returnWhitespace) { - return createToken(Token.WHITESPACE); - } - } - case 143: break; - case 54: - { return createToken(ELIPSIS); - } - case 144: break; - case 110: - { return createToken(KEYWORD_IMPLEMENTS); - } - case 145: break; - case 16: - { return createToken(SEPARATOR_RBRACKET); - } - case 146: break; - case 61: - { return createToken(OPERATOR_RSHIFT2); - } - case 147: break; - case 8: - { return createToken(LITERAL_CHAR, true); - } - case 148: break; - case 96: - { return createToken(KEYWORD_EXTENDS); - } - case 149: break; - case 84: - { return createToken(KEYWORD_CONST); - } - case 150: break; - case 94: - { return createToken(KEYWORD_DOUBLE); - } - case 151: break; - case 36: - { return createToken(KEYWORD_IF); - } - case 152: break; - case 83: - { return createToken(KEYWORD_CLASS); - } - case 153: break; - case 63: - { return createToken(LITERAL_FP); - } - case 154: break; - case 39: - { return createToken(OPERATOR_GTE); - } - case 155: break; - case 56: - { return createToken(KEYWORD_FOR); - } - case 156: break; - case 32: - { if (returnComments) { - return createToken(Token.COMMENT); - } - } - case 157: break; - case 70: - { return createToken(KEYWORD_BYTE); - } - case 158: break; - case 30: - { return createToken(OPERATOR_BITWISE_XOR); - } - case 159: break; - case 18: - { return createToken(SEPARATOR_COMMA); - } - case 160: break; - case 14: - { return createToken(SEPARATOR_RBRACE); - } - case 161: break; - case 41: - { return createToken(OPERATOR_LTE); - } - case 162: break; - case 57: - { return createToken(LITERAL_CHAR); - } - case 163: break; - case 58: - { return createToken(KEYWORD_NEW); - } - case 164: break; - case 48: - { return createToken(OPERATOR_PLUS_EQUALS); - } - case 165: break; - case 81: - { return createToken(KEYWORD_BREAK); - } - case 166: break; - case 1: - { return createToken(IDENTIFIER, true); - } - case 167: break; - case 9: - { return createToken(LITERAL_STRING, true); - } - case 168: break; - case 4: - { return createToken(OPERATOR_DIVIDE); - } - case 169: break; - case 29: - { return createToken(OPERATOR_MINUS); - } - case 170: break; - case 98: - { return createToken(KEYWORD_BOOLEAN); - } - case 171: break; - case 93: - { return createToken(KEYWORD_IMPORT); - } - case 172: break; - case 20: - { return createToken(OPERATOR_GT); - } - case 173: break; - case 47: - { return createToken(OPERATOR_LOGICAL_OR); - } - case 174: break; - case 2: - { return createToken(IDENTIFIER); - } - case 175: break; - case 53: - { return createToken(OPERATOR_MOD_EQUALS); - } - case 176: break; - case 100: - { return createToken(KEYWORD_PRIVATE); - } - case 177: break; - case 55: - { return createToken(KEYWORD_TRY); - } - case 178: break; - case 25: - { return createToken(OPERATOR_COLON); - } - case 179: break; - case 68: - { return createToken(KEYWORD_LONG); - } - case 180: break; - case 6: - { return createToken(LITERAL_INT); - } - case 181: break; - case 13: - { return createToken(SEPARATOR_LBRACE); - } - case 182: break; - case 45: - { return createToken(OPERATOR_LOGICAL_AND); - } - case 183: break; - case 21: - { return createToken(OPERATOR_LT); - } - case 184: break; - case 78: - { return createToken(KEYWORD_FINAL); - } - case 185: break; - case 24: - { return createToken(OPERATOR_QUESTION); - } - case 186: break; - case 19: - { return createToken(OPERATOR_EQUALS); - } - case 187: break; - case 108: - { return createToken(KEYWORD_PROTECTED); - } - case 188: break; - case 65: - { return createToken(KEYWORD_THIS); - } - case 189: break; - case 44: - { return createToken(OPERATOR_BITWISE_AND_EQUALS); - } - case 190: break; - case 109: - { return createToken(KEYWORD_INSTANCEOF); - } - case 191: break; - case 99: - { return createToken(KEYWORD_DEFAULT); - } - case 192: break; - case 40: - { return createToken(OPERATOR_RSHIFT); - } - case 193: break; - case 64: - { return createToken(LITERAL_BOOLEAN); - } - case 194: break; - case 67: - { return createToken(KEYWORD_ENUM); - } - case 195: break; - case 97: - { return createToken(KEYWORD_FINALLY); - } - case 196: break; - case 79: - { return createToken(KEYWORD_SUPER); - } - case 197: break; - case 77: - { return createToken(KEYWORD_FLOAT); - } - case 198: break; - case 101: - { return createToken(KEYWORD_PACKAGE); - } - case 199: break; - case 59: - { return createToken(KEYWORD_INT); - } - case 200: break; - case 22: - { return createToken(OPERATOR_LOGICAL_NOT); - } - case 201: break; - case 111: - { return createToken(KEYWORD_SYNCHRONIZED); - } - case 202: break; - case 73: - { return createToken(KEYWORD_GOTO); - } - case 203: break; - case 10: - { return createToken(ANNOTATION_START); - } - case 204: break; - case 12: - { return createToken(SEPARATOR_RPAREN); - } - case 205: break; - case 27: - { return createToken(OPERATOR_BITWISE_OR); - } - case 206: break; - case 49: - { return createToken(OPERATOR_INCREMENT); - } - case 207: break; - case 107: - { return createToken(KEYWORD_INTERFACE); - } - case 208: break; - case 88: - { return createToken(KEYWORD_RETURN); - } - case 209: break; - case 72: - { return createToken(KEYWORD_CHAR); - } - case 210: break; - case 17: - { return createToken(SEPARATOR_SEMICOLON); - } - case 211: break; - case 50: - { return createToken(OPERATOR_MINUS_EQUALS); - } - case 212: break; - case 33: - { return createToken(OPERATOR_DIVIDE_EQUALS); - } - case 213: break; - case 52: - { return createToken(OPERATOR_BITWISE_XOR_EQUALS); - } - case 214: break; - case 42: - { return createToken(OPERATOR_LSHIFT); - } - case 215: break; - case 103: - { return createToken(KEYWORD_STRICTFP); - } - case 216: break; - case 90: - { return createToken(KEYWORD_STATIC); - } - case 217: break; - case 85: - { return createToken(KEYWORD_WHILE); - } - case 218: break; - case 37: - { return createToken(KEYWORD_DO); - } - case 219: break; - case 106: - { return createToken(KEYWORD_TRANSIENT); - } - case 220: break; - case 86: - { if (keepLastDocComment) { - lastDocComment = yytext(); - } - if (returnComments) { - return createToken(Token.DOC_COMMENT); - } - } - case 221: break; - case 82: - { return createToken(KEYWORD_CATCH); - } - case 222: break; - default: - if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { - zzAtEOF = true; - return null; - } - else { - zzScanError(ZZ_NO_MATCH); - } - } - } - } - - -} diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/Token.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/Token.java deleted file mode 100644 index a66d1d72..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/Token.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.rjc.lexer; - - -/** - * A lexical token in a Java file. - * - * @author Robert Futrell - * @version 0.1 - */ -public interface Token extends TokenTypes { - - public int getColumn(); - - - public String getLexeme(); - - - public int getLength(); - - - public int getLine(); - - - public int getOffset(); - - - public int getType(); - - - public boolean isBasicType(); - - - public boolean isIdentifier(); - - - public boolean isInvalid(); - - - public boolean isOperator(); - - - public boolean isType(int type); - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/TokenImpl.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/TokenImpl.java deleted file mode 100644 index 89cbf673..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/TokenImpl.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.rjc.lexer; - - -/** - * Implementation of a token in a Java source file. - * - * @author Robert Futrell - * @version 1.0 - */ -class TokenImpl implements Token { - - private int type; - - /** - * The token's text. - */ - private String lexeme; - - /** - * The line the token is on. - */ - private int line; - - /** - * The column the token is on. - */ - private int column; - - /** - * The absolute offset into the source of the token. - */ - private int offset; - - /** - * Whether the token is invalid (e.g. an invalid char of String). - */ - private boolean invalid; - - - public TokenImpl(int type, String lexeme, int line, int column, int offs) { - this(type, lexeme, line, column, offs, false); - } - - - public TokenImpl(int type, String lexeme, int line, int column, int offs, - boolean invalid) { - this.type = type; - this.lexeme = lexeme; - this.line = line; - this.column = column; - this.offset = offs; - this.invalid = invalid; - } - - - @Override - public boolean equals(Object obj) { - if (obj==this) { - return true; - } - if (obj instanceof Token) { - Token t2 = (Token)obj; - return type==t2.getType() && lexeme.equals(t2.getLexeme()) && - line==t2.getLine() && column==t2.getColumn() && - invalid==t2.isInvalid(); - } - return false; - } - - - public int getColumn() { - return column; - } - - - public int getLength() { - return lexeme.length(); - } - - - public String getLexeme() { - return lexeme; - } - - - public int getLine() { - return line; - } - - - public int getOffset() { - return offset; - } - - - public int getType() { - return type; - } - - - @Override - public int hashCode() { - return lexeme.hashCode(); - } - - - public boolean isBasicType() { - switch (getType()) { - case KEYWORD_BYTE: - case KEYWORD_SHORT: - case KEYWORD_CHAR: - case KEYWORD_INT: - case KEYWORD_LONG: - case KEYWORD_FLOAT: - case KEYWORD_DOUBLE: - case KEYWORD_BOOLEAN: - return true; - default: - return false; - } - } - - - public boolean isIdentifier() { - return (getType()&IDENTIFIER)>0; - } - - - public boolean isInvalid() { - return invalid; - } - - - public boolean isOperator() { - return (getType()&OPERATOR)>0; - } - - - public boolean isType(int type) { - return this.type==type; - } - - - @Override - public String toString() { - return "[TokenImpl: " + - "type=" + type + - "; lexeme=\"" + lexeme + "\"" + - "; line=" + getLine() + - "; col=" + getColumn() + - "; offs=" + getOffset() + - "; invalid=" + isInvalid() + - "]"; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/TokenTypes.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/TokenTypes.java deleted file mode 100644 index 90956af0..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/rjc/lexer/TokenTypes.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.rjc.lexer; - - -/** - * All possible token types returned by this lexer. - * - * @author Robert Futrell - * @version 1.0 - */ -public interface TokenTypes { - - public static final int KEYWORD = (0x01)<<16; - public static final int DATA_TYPE = (0x02|KEYWORD)<<16; - public static final int IDENTIFIER = (0x04)<<16; - public static final int COMMENT = (0x08)<<16; - public static final int DOC_COMMENT = (0x10|COMMENT)<<16; - public static final int WHITESPACE = (0x20)<<16; - public static final int LITERAL = (0x40)<<16; - public static final int SEPARATOR = (0x80)<<16; - public static final int OPERATOR = (0x100)<<16; - public static final int ASSIGNMENT_OPERATOR = (0x200|OPERATOR)<<16; - public static final int ANNOTATION_START = (0x400)<<16; - public static final int ELIPSIS = (0x800)<<16; - - public static final int KEYWORD_ABSTRACT = KEYWORD|1; - public static final int KEYWORD_ASSERT = KEYWORD|2; - public static final int KEYWORD_BOOLEAN = DATA_TYPE|3; - public static final int KEYWORD_BREAK = KEYWORD|4; - public static final int KEYWORD_BYTE = DATA_TYPE|5; - public static final int KEYWORD_CASE = KEYWORD|6; - public static final int KEYWORD_CATCH = KEYWORD|7; - public static final int KEYWORD_CHAR = DATA_TYPE|8; - public static final int KEYWORD_CLASS = KEYWORD|9; - public static final int KEYWORD_CONST = KEYWORD|10; - public static final int KEYWORD_CONTINUE = KEYWORD|11; - public static final int KEYWORD_DEFAULT = KEYWORD|12; - public static final int KEYWORD_DO = KEYWORD|13; - public static final int KEYWORD_DOUBLE = DATA_TYPE|14; - public static final int KEYWORD_ELSE = KEYWORD|15; - public static final int KEYWORD_ENUM = KEYWORD|16; - public static final int KEYWORD_EXTENDS = KEYWORD|17; - public static final int KEYWORD_FINAL = KEYWORD|18; - public static final int KEYWORD_FINALLY = KEYWORD|19; - public static final int KEYWORD_FLOAT = DATA_TYPE|20; - public static final int KEYWORD_FOR = KEYWORD|21; - public static final int KEYWORD_GOTO = KEYWORD|22; - public static final int KEYWORD_IF = KEYWORD|23; - public static final int KEYWORD_IMPLEMENTS = KEYWORD|24; - public static final int KEYWORD_IMPORT = KEYWORD|25; - public static final int KEYWORD_INSTANCEOF = KEYWORD|26; - public static final int KEYWORD_INT = DATA_TYPE|27; - public static final int KEYWORD_INTERFACE = KEYWORD|28; - public static final int KEYWORD_LONG = DATA_TYPE|29; - public static final int KEYWORD_NATIVE = KEYWORD|30; - public static final int KEYWORD_NEW = KEYWORD|31; - public static final int KEYWORD_PACKAGE = KEYWORD|32; - public static final int KEYWORD_PRIVATE = KEYWORD|33; - public static final int KEYWORD_PROTECTED = KEYWORD|34; - public static final int KEYWORD_PUBLIC = KEYWORD|35; - public static final int KEYWORD_RETURN = KEYWORD|36; - public static final int KEYWORD_SHORT = DATA_TYPE|37; - public static final int KEYWORD_STATIC = KEYWORD|38; - public static final int KEYWORD_STRICTFP = KEYWORD|39; - public static final int KEYWORD_SUPER = KEYWORD|40; - public static final int KEYWORD_SWITCH = KEYWORD|41; - public static final int KEYWORD_SYNCHRONIZED = KEYWORD|42; - public static final int KEYWORD_THIS = KEYWORD|43; - public static final int KEYWORD_THROW = KEYWORD|44; - public static final int KEYWORD_THROWS = KEYWORD|45; - public static final int KEYWORD_TRANSIENT = KEYWORD|46; - public static final int KEYWORD_TRY = KEYWORD|47; - public static final int KEYWORD_VOID = KEYWORD|48; - public static final int KEYWORD_VOLATILE = KEYWORD|49; - public static final int KEYWORD_WHILE = KEYWORD|50; - - public static final int LITERAL_INT = LITERAL|1; - public static final int LITERAL_FP = LITERAL|2; - public static final int LITERAL_BOOLEAN = LITERAL|3; - public static final int LITERAL_CHAR = LITERAL|4; - public static final int LITERAL_STRING = LITERAL|5; - public static final int LITERAL_NULL = LITERAL|6; - - public static final int SEPARATOR_LPAREN = SEPARATOR|1; - public static final int SEPARATOR_RPAREN = SEPARATOR|2; - public static final int SEPARATOR_LBRACE = SEPARATOR|3; - public static final int SEPARATOR_RBRACE = SEPARATOR|4; - public static final int SEPARATOR_LBRACKET = SEPARATOR|5; - public static final int SEPARATOR_RBRACKET = SEPARATOR|6; - public static final int SEPARATOR_SEMICOLON = SEPARATOR|7; - public static final int SEPARATOR_COMMA = SEPARATOR|8; - public static final int SEPARATOR_DOT = SEPARATOR|9; - - public static final int OPERATOR_EQUALS = ASSIGNMENT_OPERATOR|1; - public static final int OPERATOR_GT = OPERATOR|2; - public static final int OPERATOR_LT = OPERATOR|3; - public static final int OPERATOR_LOGICAL_NOT = OPERATOR|4; - public static final int OPERATOR_BITWISE_NOT = OPERATOR|5; - public static final int OPERATOR_QUESTION = OPERATOR|6; - public static final int OPERATOR_COLON = OPERATOR|7; - public static final int OPERATOR_EQUALS_EQUALS = OPERATOR|8; - public static final int OPERATOR_LTE = OPERATOR|9; - public static final int OPERATOR_GTE = OPERATOR|10; - public static final int OPERATOR_NE = OPERATOR|11; - public static final int OPERATOR_LOGICAL_AND = OPERATOR|12; - public static final int OPERATOR_LOGICAL_OR = OPERATOR|13; - public static final int OPERATOR_INCREMENT = OPERATOR|14; - public static final int OPERATOR_DECREMENT = OPERATOR|15; - public static final int OPERATOR_PLUS = OPERATOR|16; - public static final int OPERATOR_MINUS = OPERATOR|17; - public static final int OPERATOR_TIMES = OPERATOR|18; - public static final int OPERATOR_DIVIDE = OPERATOR|19; - public static final int OPERATOR_BITWISE_AND = OPERATOR|20; - public static final int OPERATOR_BITWISE_OR = OPERATOR|21; - public static final int OPERATOR_BITWISE_XOR = OPERATOR|22; - public static final int OPERATOR_MOD = OPERATOR|23; - public static final int OPERATOR_LSHIFT = OPERATOR|24; - public static final int OPERATOR_RSHIFT = OPERATOR|25; - public static final int OPERATOR_RSHIFT2 = OPERATOR|26; - public static final int OPERATOR_PLUS_EQUALS = ASSIGNMENT_OPERATOR|27; - public static final int OPERATOR_MINUS_EQUALS = ASSIGNMENT_OPERATOR|28; - public static final int OPERATOR_TIMES_EQUALS = ASSIGNMENT_OPERATOR|29; - public static final int OPERATOR_DIVIDE_EQUALS = ASSIGNMENT_OPERATOR|30; - public static final int OPERATOR_BITWISE_AND_EQUALS = ASSIGNMENT_OPERATOR|31; - public static final int OPERATOR_BITWISE_OR_EQUALS = ASSIGNMENT_OPERATOR|32; - public static final int OPERATOR_BITWISE_XOR_EQUALS = ASSIGNMENT_OPERATOR|33; - public static final int OPERATOR_MOD_EQUALS = ASSIGNMENT_OPERATOR|34; - public static final int OPERATOR_LSHIFT_EQUALS = ASSIGNMENT_OPERATOR|35; - public static final int OPERATOR_RSHIFT_EQUALS = ASSIGNMENT_OPERATOR|36; - public static final int OPERATOR_RSHIFT2_EQUALS = ASSIGNMENT_OPERATOR|37; - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/notices/ParserNotice.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/notices/ParserNotice.java deleted file mode 100644 index 4f2da8fa..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/rjc/notices/ParserNotice.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.rjc.notices; - -import org.fife.rsta.ac.bsh.rjc.lexer.Token; - - -/** - * A notice (e.g., a warning or error) from a parser. - * - * @author Robert Futrell - * @version 0.1 - */ -public class ParserNotice { - - private int line; - private int column; - private int length; - private String message; - - - public ParserNotice(Token t, String msg) { - line = t.getLine(); - column = t.getColumn(); - length = t.getLexeme().length(); - message = msg; - } - - - /** - * Constructor. - * - * @param line The line of the notice. - * @param column The column of the notice. - * @param length The length of the code the message is concerned with. - * @param message The message. - */ - public ParserNotice(int line, int column, int length, String message) { - this.line = line; - this.column = column; - this.length = length; - this.message = message; - } - - - /** - * Returns the character offset into the line of the parser notice, - * if any. - * - * @return The column. - */ - public int getColumn() { - return column; - } - - - /** - * Returns the length of the code the message is concerned with. - * - * @return The length of the code the message is concerned with. - */ - public int getLength() { - return length; - } - - - /** - * Returns the line number the notice is about, if any. - * - * @return The line number. - */ - public int getLine() { - return line; - } - - - /** - * Returns the message from the parser. - * - * @return The message from the parser. - */ - public String getMessage() { - return message; - } - - - /** - * Returns a string representation of this parser notice. - * - * @return This parser notice as a string. - */ - @Override - public String toString() { - return "(" + getLine() + ", " + getColumn() + ": " + getMessage(); - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/parser/ASTFactory.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/parser/ASTFactory.java deleted file mode 100644 index eef3b39b..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/rjc/parser/ASTFactory.java +++ /dev/null @@ -1,888 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.rjc.parser; - -import org.fife.rsta.ac.bsh.rjc.lexer.Token; -import org.fife.rsta.ac.bsh.rjc.lexer.Scanner; -import org.fife.rsta.ac.bsh.rjc.lexer.TokenTypes; -import java.io.EOFException; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import org.fife.rsta.ac.bsh.rjc.ast.CodeBlock; -import org.fife.rsta.ac.bsh.rjc.ast.CompilationUnit; -import org.fife.rsta.ac.bsh.rjc.ast.FormalParameter; -import org.fife.rsta.ac.bsh.rjc.ast.ImportDeclaration; -import org.fife.rsta.ac.bsh.rjc.ast.LocalVariable; -import org.fife.rsta.ac.bsh.rjc.ast.Method; -import org.fife.rsta.ac.bsh.rjc.ast.NormalClassDeclaration; -import org.fife.rsta.ac.bsh.rjc.ast.Package; -import org.fife.rsta.ac.bsh.rjc.ast.TypeDeclaration; -import org.fife.rsta.ac.bsh.rjc.ast.TypeDeclarationContainer; -import org.fife.rsta.ac.bsh.rjc.lang.Annotation; -import org.fife.rsta.ac.bsh.rjc.lang.Modifiers; -import org.fife.rsta.ac.bsh.rjc.lang.Type; -import org.fife.rsta.ac.bsh.rjc.lang.TypeArgument; -import org.fife.rsta.ac.bsh.rjc.notices.ParserNotice; - -/** - * Generates an abstract syntax tree for a Java source file. - * - * @author Robert Futrell - * @version 1.0 - */ -public class ASTFactory implements TokenTypes { - - private static final boolean DEBUG = false; - - public ASTFactory() { - } - - /** - * Checks whether a local variable's name collides with a local variable - * defined earlier. Note that this method assumes that it is called - * immediately whenever a variable is parsed, thus any other variables - * declared in a code block were declared before the one being checked. - * - * @param cu The compilation unit. - * @param lVar The just-scanned local variable. - * @param block The code block the variable is in. - * @param m The method the (possibly nested) code block block - * is in, or null for none. - */ - private void checkForDuplicateLocalVarNames(CompilationUnit cu, - Token lVar, CodeBlock block, Method m) { - - String name = lVar.getLexeme(); - boolean found = false; - - // See if a local variable defined previously in this block has the - // same name. - for (int i = 0; i < block.getLocalVarCount(); i++) { - LocalVariable otherLocal = block.getLocalVar(i); - if (name.equals(otherLocal.getName())) { - cu.addParserNotice(lVar, "Duplicate local variable: " + name); - found = true; - break; - } - } - - // If not... - if (!found) { - - // If this was a nested code block, check previously-defined - // variables in the parent block. - if (block.getParent() != null) { - checkForDuplicateLocalVarNames(cu, lVar, block.getParent(), m); - } // If this was the highest-level code block, if we're in the body - // of a method, check the method's parameters. - else if (m != null) { - for (int i = 0; i < m.getParameterCount(); i++) { - FormalParameter param = m.getParameter(i); - if (name.equals(param.getName())) { - cu.addParserNotice(lVar, "Duplicate local variable: " + name); - break; - } - } - } - - } - - } - - /** - * Assumes t is the actual '@foobar' annotation token. - * - * @param cu - * @param s - * @return - * @throws IOException - */ - private Annotation _getAnnotation(CompilationUnit cu, Scanner s) - throws IOException { - - s.yylexNonNull(ANNOTATION_START, "Annotation expected"); - Type type = _getType(cu, s); - - if (s.yyPeekCheckType() == SEPARATOR_LPAREN) { - s.yylex(); - // TODO: Read rest of Annotation stuff - s.eatThroughNextSkippingBlocks(SEPARATOR_RPAREN); - } - - Annotation a = new Annotation(type); - return a; - - } - - private CodeBlock _getScript(CompilationUnit cu, CodeBlock parent, Method m, - Scanner s, boolean isStatic) throws IOException { - return _getScript(cu, parent, m, s, isStatic, 1); - } - - /** - * Parses a block of code. This should not be called. - * - * @param parent The parent code block, or null if none (i.e. - * this is the body of a method, a static initializer block, etc.). - * @param m The method containing this block, or null if this - * block is not part of a method. - * @param s The scanner. - * @param isStatic Whether this is a static code block. - * @param depth The nested depth of this code block. - */ - private CodeBlock _getBlock(CompilationUnit cu, CodeBlock parent, - Method m, Scanner s, - boolean isStatic, int depth) throws IOException { - - log("Entering _getBlock() (" + depth + ")"); - - // TODO: Implement me to get variable declarations. - Token t = s.yylexNonNull(SEPARATOR_LBRACE, "'{' expected"); - CodeBlock block = new CodeBlock(isStatic, s.createOffset(t.getOffset())); - block.setParent(parent); - boolean atStatementStart = true; - - OUTER: - while (true) { - - // Don't bail if they have unmatched parens (for example), just - // return the current status of the block. - //t = s.yylexNonNull("Unexpected end of input"); - if ((t = s.yylex()) == null) { - log("Exiting _getBlock() - eos (" + depth + ")"); - block.setDeclarationEndOffset(s.createOffset(s.getOffset())); - return block; - } - - int type = t.getType(); - boolean isFinal = false; - - switch (type) { - - case SEPARATOR_LBRACE: - s.yyPushback(t); - CodeBlock child = _getBlock(cu, block, m, s, isStatic, depth + 1); - block.add(child); - atStatementStart = true; - break; - - case SEPARATOR_RBRACE: - block.setDeclarationEndOffset(s.createOffset(t.getOffset())); - break OUTER; - - case KEYWORD_TRY: - t = s.yyPeekNonNull(SEPARATOR_LBRACE, SEPARATOR_LPAREN, "'{' or '(' expected"); - if (t.getType() == SEPARATOR_LPAREN) { // Auto-closeable stuff - // TODO: Get block-scoped var(s) - s.eatParenPairs(); - } - s.yyPeekNonNull(SEPARATOR_LBRACE, "'{' expected"); - CodeBlock tryBlock = _getBlock(cu, block, m, s, isStatic, depth + 1); - block.add(tryBlock); - while (s.yyPeekCheckType() == KEYWORD_CATCH - && s.yyPeekCheckType(2) == SEPARATOR_LPAREN) { - s.yylex(); // catch - s.yylex(); // lparen - Type exType = null; - Token var = null; - boolean multiCatch = false; - do { - isFinal = false; - Token temp = s.yyPeekNonNull(IDENTIFIER, KEYWORD_FINAL, "Throwable type expected"); - if (temp.isType(KEYWORD_FINAL)) { - isFinal = true; - s.yylex(); - } - s.yyPeekNonNull(IDENTIFIER, "Variable declarator expected"); - exType = _getType(cu, s); // Not good for multi-catch! - var = s.yylexNonNull(IDENTIFIER, OPERATOR_BITWISE_OR, "Variable declarator expected"); - multiCatch |= var.isType(OPERATOR_BITWISE_OR); - } while (var.isType(OPERATOR_BITWISE_OR)); - s.yylexNonNull(SEPARATOR_RPAREN, "')' expected"); - s.yyPeekNonNull(SEPARATOR_LBRACE, "'{' expected"); - CodeBlock catchBlock = _getBlock(cu, block, m, s, false, depth); - int offs = var.getOffset(); // Not actually in block! - if (multiCatch) { - // TODO: With Java 7's multi-catch, calculate - // least upper bound for exception type: - // http://cr.openjdk.java.net/~darcy/ProjectCoin/ProjectCoin-Documentation-v0.83.html#multi_catch - exType = new Type("java"); - exType.addIdentifier("lang", null); - exType.addIdentifier("Throwable", null); - } - LocalVariable localVar = new LocalVariable(s, isFinal, exType, offs, var.getLexeme()); - checkForDuplicateLocalVarNames(cu, var, block, m); - catchBlock.addLocalVariable(localVar); - block.add(catchBlock); - } - break; - - case KEYWORD_FOR: - // TODO: Get local var (e.g. "int i", "Iterator i", etc.) - // Fall through - case KEYWORD_WHILE: - int nextType = s.yyPeekCheckType(); - while (nextType != -1 && nextType != SEPARATOR_LPAREN) { - t = s.yylex(); // Grab the (unexpected) token - if (t != null) { // Should always be true - ParserNotice pn = new ParserNotice(t, "Unexpected token"); - cu.addParserNotice(pn); - } - nextType = s.yyPeekCheckType(); - } - if (nextType == SEPARATOR_LPAREN) { - s.eatParenPairs(); - } - nextType = s.yyPeekCheckType(); - if (nextType == SEPARATOR_LBRACE) { - child = _getBlock(cu, block, m, s, isStatic, depth + 1); - block.add(child); - atStatementStart = true; - } - break; - -// NOTE: The code below is supposed to try to parse code blocks and identify -// variable declarations. This does work somewhat, but the problem is that -// our parsing of type parameters isn't good enough, and lines like: -// for (int i=0; i" (even though the closing '>' isn't -// there, but that's not the big problem really!). We should be able to check -// whether our type parameters are well-formed, and if they aren't, then assume -// push all tokens back, and assume that the '<' was a less-than operator. -// It's the "push all tokens back" that's tough for us at the moment, as we've -// lost most of the tokens (there may be an arbitrary number that have been -// parsed and discarded). - case KEYWORD_FINAL: - isFinal = true; - t = s.yylexNonNull("Unexpected end of file"); - // Fall through - - default: - if (t.isType(SEPARATOR_SEMICOLON)) { - atStatementStart = true; - break; - } else if (atStatementStart && (t.isBasicType() || (t.isIdentifier()))) { - s.yyPushback(t); - // TODO: This is very inefficient - Type varType = null; - try { - varType = _getType(cu, s, true); - } catch (IOException ioe) { // Not a var declaration - s.eatUntilNext(SEPARATOR_SEMICOLON, SEPARATOR_LBRACE, SEPARATOR_RBRACE); - // Only needed if ended on ';' or '}', but... - atStatementStart = true; - break; - } - if (s.yyPeekCheckType() == IDENTIFIER) { - while ((t = s.yylexNonNull(IDENTIFIER, "Variable name expected (type==" + varType.toString() + ")")) != null) { - int arrayDepth = s.skipBracketPairs(); - varType.incrementBracketPairCount(arrayDepth); - String varDec = varType.toString() + " " + t.getLexeme(); - log(">>> Variable -- " + varDec + " (line " + t.getLine() + ")"); - int offs = t.getOffset(); - String name = t.getLexeme(); - LocalVariable lVar = new LocalVariable(s, isFinal, varType, offs, name); - checkForDuplicateLocalVarNames(cu, t, block, m); - block.addLocalVariable(lVar); - nextType = s.yyPeekCheckType(); - // A "valid" nextType would be '=', ',' or ';'. - // If it's an '=', skip past the assignment. - if (nextType == OPERATOR_EQUALS) { - Token temp = s.eatThroughNextSkippingBlocksAndStuffInParens(SEPARATOR_COMMA, SEPARATOR_SEMICOLON); - if (temp != null) { - s.yyPushback(temp); - } - nextType = s.yyPeekCheckType(); - } - // If next is a comma, loop to read the next local - // var. Otherwise, whether or not it's valid, - // eat until the end of the statement. - if (nextType != SEPARATOR_COMMA) { - s.eatThroughNextSkippingBlocks(SEPARATOR_SEMICOLON); - break; - } - s.yylex(); // Eat the comma (does nothing if EOS) - } - } - } else { - atStatementStart = false; - } - break; - - } - - } - - log("Exiting _getBlock() (" + depth + ")"); - return block; - - } - - private CodeBlock _getScript(CompilationUnit cu, CodeBlock parent, - Method m, Scanner s, - boolean isStatic, int depth) throws IOException { - - log("Entering _getScript() (" + depth + ")"); - - // TODO: Implement me to get variable declarations. - Token t = s.yyPeek(); - CodeBlock block = new CodeBlock(isStatic, s.createOffset(t.getOffset())); - block.setParent(parent); - boolean atStatementStart = true; - - OUTER: - while (true) { - - // Don't bail if they have unmatched parens (for example), just - // return the current status of the block. - //t = s.yylexNonNull("Unexpected end of input"); - if ((t = s.yylex()) == null) { - log("Exiting _getScript() - eos (" + depth + ")"); - block.setDeclarationEndOffset(s.createOffset(s.getOffset())); - return block; - } - - int type = t.getType(); - boolean isFinal = false; - - switch (type) { - - case SEPARATOR_LBRACE: - s.yyPushback(t); - CodeBlock child = _getBlock(cu, block, m, s, isStatic, depth + 1); - block.add(child); - atStatementStart = true; - break; - - case SEPARATOR_RBRACE: - block.setDeclarationEndOffset(s.createOffset(t.getOffset())); - break OUTER; - - case KEYWORD_TRY: - t = s.yyPeekNonNull(SEPARATOR_LBRACE, SEPARATOR_LPAREN, "'{' or '(' expected"); - if (t.getType() == SEPARATOR_LPAREN) { // Auto-closeable stuff - // TODO: Get block-scoped var(s) - s.eatParenPairs(); - } - s.yyPeekNonNull(SEPARATOR_LBRACE, "'{' expected"); - CodeBlock tryBlock = _getBlock(cu, block, m, s, isStatic, depth + 1); - block.add(tryBlock); - while (s.yyPeekCheckType() == KEYWORD_CATCH - && s.yyPeekCheckType(2) == SEPARATOR_LPAREN) { - s.yylex(); // catch - s.yylex(); // lparen - Type exType = null; - Token var = null; - boolean multiCatch = false; - do { - isFinal = false; - Token temp = s.yyPeekNonNull(IDENTIFIER, KEYWORD_FINAL, "Throwable type expected"); - if (temp.isType(KEYWORD_FINAL)) { - isFinal = true; - s.yylex(); - } - s.yyPeekNonNull(IDENTIFIER, "Variable declarator expected"); - exType = _getType(cu, s); // Not good for multi-catch! - var = s.yylexNonNull(IDENTIFIER, OPERATOR_BITWISE_OR, "Variable declarator expected"); - multiCatch |= var.isType(OPERATOR_BITWISE_OR); - } while (var.isType(OPERATOR_BITWISE_OR)); - s.yylexNonNull(SEPARATOR_RPAREN, "')' expected"); - s.yyPeekNonNull(SEPARATOR_LBRACE, "'{' expected"); - CodeBlock catchBlock = _getBlock(cu, block, m, s, false, depth); - int offs = var.getOffset(); // Not actually in block! - if (multiCatch) { - // TODO: With Java 7's multi-catch, calculate - // least upper bound for exception type: - // http://cr.openjdk.java.net/~darcy/ProjectCoin/ProjectCoin-Documentation-v0.83.html#multi_catch - exType = new Type("java"); - exType.addIdentifier("lang", null); - exType.addIdentifier("Throwable", null); - } - LocalVariable localVar = new LocalVariable(s, isFinal, exType, offs, var.getLexeme()); - checkForDuplicateLocalVarNames(cu, var, block, m); - catchBlock.addLocalVariable(localVar); - block.add(catchBlock); - } - break; - - case KEYWORD_FOR: - // TODO: Get local var (e.g. "int i", "Iterator i", etc.) - // Fall through - case KEYWORD_WHILE: - int nextType = s.yyPeekCheckType(); - while (nextType != -1 && nextType != SEPARATOR_LPAREN) { - t = s.yylex(); // Grab the (unexpected) token - if (t != null) { // Should always be true - ParserNotice pn = new ParserNotice(t, "Unexpected token"); - cu.addParserNotice(pn); - } - nextType = s.yyPeekCheckType(); - } - if (nextType == SEPARATOR_LPAREN) { - s.eatParenPairs(); - } - nextType = s.yyPeekCheckType(); - if (nextType == SEPARATOR_LBRACE) { - child = _getBlock(cu, block, m, s, isStatic, depth + 1); - block.add(child); - atStatementStart = true; - } - break; - -// NOTE: The code below is supposed to try to parse code blocks and identify -// variable declarations. This does work somewhat, but the problem is that -// our parsing of type parameters isn't good enough, and lines like: -// for (int i=0; i" (even though the closing '>' isn't -// there, but that's not the big problem really!). We should be able to check -// whether our type parameters are well-formed, and if they aren't, then assume -// push all tokens back, and assume that the '<' was a less-than operator. -// It's the "push all tokens back" that's tough for us at the moment, as we've -// lost most of the tokens (there may be an arbitrary number that have been -// parsed and discarded). - case KEYWORD_FINAL: - isFinal = true; - t = s.yylexNonNull("Unexpected end of file"); - // Fall through - - default: - if (t.isType(SEPARATOR_SEMICOLON)) { - atStatementStart = true; - break; - } else if (atStatementStart && (t.isBasicType() || (t.isIdentifier()))) { - s.yyPushback(t); - // TODO: This is very inefficient - Type varType = null; - try { - varType = _getType(cu, s, true); - } catch (IOException ioe) { // Not a var declaration - s.eatUntilNext(SEPARATOR_SEMICOLON, SEPARATOR_LBRACE, SEPARATOR_RBRACE); - // Only needed if ended on ';' or '}', but... - atStatementStart = true; - break; - } - if (s.yyPeekCheckType() == IDENTIFIER) { - while ((t = s.yylexNonNull(IDENTIFIER, "Variable name expected (type==" + varType.toString() + ")")) != null) { - int arrayDepth = s.skipBracketPairs(); - varType.incrementBracketPairCount(arrayDepth); - String varDec = varType.toString() + " " + t.getLexeme(); - log(">>> Variable -- " + varDec + " (line " + t.getLine() + ")"); - int offs = t.getOffset(); - String name = t.getLexeme(); - LocalVariable lVar = new LocalVariable(s, isFinal, varType, offs, name); - checkForDuplicateLocalVarNames(cu, t, block, m); - block.addLocalVariable(lVar); - nextType = s.yyPeekCheckType(); - // A "valid" nextType would be '=', ',' or ';'. - // If it's an '=', skip past the assignment. - if (nextType == OPERATOR_EQUALS) { - Token temp = s.eatThroughNextSkippingBlocksAndStuffInParens(SEPARATOR_COMMA, SEPARATOR_SEMICOLON); - if (temp != null) { - s.yyPushback(temp); - } - nextType = s.yyPeekCheckType(); - } - // If next is a comma, loop to read the next local - // var. Otherwise, whether or not it's valid, - // eat until the end of the statement. - if (nextType != SEPARATOR_COMMA) { - s.eatThroughNextSkippingBlocks(SEPARATOR_SEMICOLON); - break; - } - s.yylex(); // Eat the comma (does nothing if EOS) - } - } - } else { - atStatementStart = false; - } - break; - - } - - } - - log("Exiting _getScript() (" + depth + ")"); - return block; - - } - - private TypeDeclaration _getClassOrInterfaceDeclaration(CompilationUnit cu, - Scanner s, TypeDeclarationContainer addTo, Modifiers modList) - throws IOException { - - log("Entering _getClassOrInterfaceDeclaration"); - - TypeDeclaration td = _getNormalClassDeclaration(cu, s, addTo); - - log("Exiting _getClassOrInterfaceDeclaration"); - return td; - - } - - /** - * Reads tokens for a Java source file from the specified lexer and returns - * the structure of the source as an AST. - * - * @param scanner The scanner to read from. - * @return The root node of the AST. - */ - public CompilationUnit getCompilationUnit(String name, Scanner scanner) - throws IOException { - - CompilationUnit cu = new CompilationUnit(name); - - try { - - // Get annotations. - List initialAnnotations = null; // Usually none - while (scanner.yyPeekCheckType() == ANNOTATION_START) { - if (initialAnnotations == null) { - initialAnnotations = new ArrayList(1); - } - initialAnnotations.add(_getAnnotation(cu, scanner)); - } - - // Get possible "package" line. - Token t = scanner.yylex(); - if (t == null) { - return cu; - } - if (t.isType(KEYWORD_PACKAGE)) { - t = scanner.yyPeekNonNull("Identifier expected"); - int offs = t.getOffset(); - String qualifiedID = getQualifiedIdentifier(scanner); - Package pkg = new Package(scanner, offs, qualifiedID); - if (initialAnnotations != null) { - // pkg.setAnnotations(initialAnnotations); - initialAnnotations = null; - } - cu.setPackage(pkg); - scanner.yylexNonNull(SEPARATOR_SEMICOLON, "Semicolon expected"); - t = scanner.yylex(); - } - - // Go through any import statements. - OUTER: - while (t != null && t.isType(KEYWORD_IMPORT)) { - - boolean isStatic = false; - StringBuilder buf = new StringBuilder(); - t = scanner.yylexNonNull("Incomplete import statement"); - Token temp = null; - int offs = 0; - - if (t.isType(KEYWORD_STATIC)) { - isStatic = true; - t = scanner.yylexNonNull("Incomplete import statement"); - } - - if (!t.isIdentifier()) { - cu.addParserNotice(t, "Expected identifier, found: \"" - + t.getLexeme() + "\""); - scanner.eatThroughNextSkippingBlocks(SEPARATOR_SEMICOLON); - // We expect "t" to be the semicolon below - t = scanner.getMostRecentToken(); - } else { - offs = t.getOffset(); - buf.append(t.getLexeme()); - temp = scanner.yylexNonNull(SEPARATOR_DOT, SEPARATOR_SEMICOLON, - "'.' or ';' expected"); - while (temp.isType(SEPARATOR_DOT)) { - temp = scanner.yylexNonNull(IDENTIFIER, OPERATOR_TIMES, - "Identifier or '*' expected"); - if (temp.isIdentifier()) { - buf.append('.').append(temp.getLexeme()); - } else {//if (temp.getLexeme().equals("*")) { - buf.append(".*"); - temp = scanner.yylex(); // We're bailing, so scan here - break; - } - temp = scanner.yylexNonNull(KEYWORD_IMPORT, SEPARATOR_DOT, - SEPARATOR_SEMICOLON, "'.' or ';' expected"); - if (temp.isType(KEYWORD_IMPORT)) { - cu.addParserNotice(temp, "';' expected"); - t = temp; - continue OUTER; - } - } - t = temp; - } - - if (temp == null || !t.isType(SEPARATOR_SEMICOLON)) { - throw new IOException("Semicolon expected, found " + t); - } - - ImportDeclaration id = new ImportDeclaration(scanner, offs, - buf.toString(), isStatic); - cu.addImportDeclaration(id); - t = scanner.yylex(); - - } - - // class files aren't required to have TypeDeclarations. - if (t == null) { - return cu; - } - - scanner.yyPushback(t); - //TypeDeclaration td = null; - while ((/*td = */_getTypeDeclaration(cu, scanner)) != null) { - if (initialAnnotations != null) { - // td.addAnnotations(initialAnnotations); - initialAnnotations = null; - } -// cu.addTypeDeclaration(td); -// Done when the type declarations are created. - } - - } catch (IOException ioe) { - if (isDebug() && !(ioe instanceof EOFException)) { // Not just "end of file" - ioe.printStackTrace(); - } - ParserNotice notice = null; - Token lastTokenLexed = scanner.getMostRecentToken(); - if (lastTokenLexed == null) { - notice = new ParserNotice(0, 0, 5, ioe.getMessage()); - } else { - notice = new ParserNotice(lastTokenLexed, ioe.getMessage()); - } - cu.addParserNotice(notice); -//throw ioe; // Un-comment me to get the AnnotationTypeDeclaration error count in "Main" test - } - - return cu; - - } - - private NormalClassDeclaration _getNormalClassDeclaration( - CompilationUnit cu, Scanner s, TypeDeclarationContainer addTo) - throws IOException { - - log("Entering _getNormalClassDeclaration"); - - Token t = s.yylexNonNull("Identifier expected"); - s.yyPushback(t); - - NormalClassDeclaration classDec = new NormalClassDeclaration(s, - t.getOffset(), "BSH_SCRIPT"); - classDec.setPackage(cu.getPackage()); - addTo.addTypeDeclaration(classDec); - CodeBlock block = _getScript(cu, null, null, s, true); - classDec.addMember(block); - - log("Exiting _getNormalClassDeclaration"); - return classDec; - - } - - private String getQualifiedIdentifier(Scanner scanner) - throws IOException { - - Token t = null; - StringBuilder sb = new StringBuilder(); - - while ((t = scanner.yylex()).isIdentifier()) { - sb.append(t.getLexeme()); - t = scanner.yylex(); - if (t.isType(SEPARATOR_DOT)) { - sb.append('.'); - } else { - break; - } - } - - // QualifiedIdentifier has ended. - scanner.yyPushback(t); - - return sb.toString(); - - } - - // For "backwards compatibility," don't know if "false" is usually - // correct or not - private Type _getType(CompilationUnit cu, Scanner s) throws IOException { - return _getType(cu, s, false); - } - - private Type _getType(CompilationUnit cu, Scanner s, - boolean pushbackOnUnexpected) throws IOException { - - log("Entering _getType()"); - Type type = new Type(); - - Token t = s.yylexNonNull("Type expected"); - - // TODO: "void" checking is NOT in the JLS for type! Remove me - if (t.isType(KEYWORD_VOID)) { - type.addIdentifier(t.getLexeme(), null); - log("Exiting _getType(): " + type.toString()); - return type; - } else if (t.isBasicType()) { - int arrayDepth = s.skipBracketPairs(); - type.addIdentifier(t.getLexeme(), null); - type.setBracketPairCount(arrayDepth); - log("Exiting _getType(): " + type.toString()); - return type; - } - - OUTER: - while (true) { - switch (t.getType()) { - case IDENTIFIER: - List typeArgs = null; - if (s.yyPeekCheckType() == OPERATOR_LT) { - typeArgs = _getTypeArguments(cu, s); - } - type.addIdentifier(t.getLexeme(), typeArgs); - t = s.yylexNonNull("Unexpected end of input"); - if (t.isType(SEPARATOR_DOT)) { - t = s.yylexNonNull("Unexpected end of input"); - continue; - } else if (t.isType(SEPARATOR_LBRACKET)) { - s.yyPushback(t); - type.setBracketPairCount(s.skipBracketPairs()); - break OUTER; - } else { - s.yyPushback(t); - break OUTER; - } - default: - if (pushbackOnUnexpected) { - s.yyPushback(t); - } - throw new IOException("Expected identifier, found: " + t); - } - } - - log("Exiting _getType(): " + type.toString()); - return type; - - } - - private TypeArgument _getTypeArgument(CompilationUnit cu, Scanner s) - throws IOException { - - log("Entering _getTypeArgument()"); - - TypeArgument typeArg = null; - - Token t = s.yyPeekNonNull("Type or '?' expected"); - - if (t.isType(OPERATOR_QUESTION)) { - s.yylex(); // Pop the '?' off the stream. - t = s.yyPeek(); - if (t.getType() != OPERATOR_GT) { - t = s.yylexNonNull(SEPARATOR_COMMA, KEYWORD_EXTENDS, - KEYWORD_SUPER, - "',', super or extends expected"); - switch (t.getType()) { - case SEPARATOR_COMMA: - typeArg = new TypeArgument(null, 0, null); - s.yyPushback(t); - break; - case KEYWORD_EXTENDS: - Type otherType = _getType(cu, s); - typeArg = new TypeArgument(null, TypeArgument.EXTENDS, otherType); - break; - default: // KEYWORD_SUPER: - otherType = _getType(cu, s); - typeArg = new TypeArgument(null, TypeArgument.SUPER, otherType); - break; - } - } else { - typeArg = new TypeArgument(null, 0, null); - } - } else { - Type type = _getType(cu, s); - typeArg = new TypeArgument(type); - } - - log("Exiting _getTypeArgument() : " + typeArg); - return typeArg; - - } - - private List _getTypeArguments(CompilationUnit cu, Scanner s) - throws IOException { - - s.increaseTypeArgumentsLevel(); - log("Entering _getTypeArguments() (" + s.getTypeArgumentsLevel() + ")"); - - s.markResetPosition(); - s.yylexNonNull(OPERATOR_LT, "'<' expected"); - - List typeArgs = new ArrayList(1); - - Token t = null; - do { - typeArgs.add(_getTypeArgument(cu, s)); - t = s.yylexNonNull("',' or '>' expected"); - if (t.getType() != SEPARATOR_COMMA && t.getType() != OPERATOR_GT) { - // Assume we're in a code block, and are simply at the (much - // more common) case of e.g. "if (i < 7) ...". - s.resetToLastMarkedPosition(); - log("Exiting _getTypeArguments() (" + s.getTypeArgumentsLevel() + ") - NOT TYPE ARGUMENTS (" + t.getLexeme() + ")"); - s.decreaseTypeArgumentsLevel(); - return null; - } - } while (t.isType(SEPARATOR_COMMA)); - - log("Exiting _getTypeArguments() (" + s.getTypeArgumentsLevel() + ")"); - s.decreaseTypeArgumentsLevel(); - - s.clearResetPosition(); - return typeArgs; - - } - - private TypeDeclaration _getTypeDeclaration(CompilationUnit cu, - Scanner s) throws IOException { - - /* - * TypeDeclaration: - * ClassOrInterfaceDeclaration - * ';' - */ - Token t = s.yylex(); - if (t == null) { - return null; // End of source file. - } - - // Skip any semicolons. - while (t.isType(SEPARATOR_SEMICOLON)) { - t = s.yylex(); - if (t == null) { - return null; // End of source file - } - } - - s.yyPushback(t); // Probably some modifier, e.g. "public" - - String docComment = s.getLastDocComment(); - TypeDeclaration td = _getClassOrInterfaceDeclaration(cu, s, cu, null); - td.setDocComment(docComment); // May be null - return td; - - } - - private static final boolean isDebug() { - return DEBUG; - } - - private static final void log(String msg) { - if (DEBUG) { - System.out.println(msg); - } - } - -} diff --git a/src/main/java/org/fife/rsta/ac/bsh/rjc/parser/Main.java b/src/main/java/org/fife/rsta/ac/bsh/rjc/parser/Main.java deleted file mode 100644 index 1569715f..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/rjc/parser/Main.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.rjc.parser; - -import org.fife.rsta.ac.bsh.rjc.lexer.Scanner; -import java.io.*; -import java.util.ArrayList; -import java.util.List; - - - -/** - * Test application for the Java scanner. - * - * @author Robert Futrell - * @version 1.0 - */ -public class Main { - - /** - * If this system property is set to "true", - * output will not be written to stdout for each file. - */ - public static final String PROPERTY_NO_OUTPUT = "no.output"; - - private static final boolean LOG = !"true".equals( - System.getProperty(PROPERTY_NO_OUTPUT)); - - - private static void log(Object text) { - if (LOG) { - System.out.println(text); - } - } - - - /** - * Program entry point. - * - * @param args Command line arguments. - * @throws IOException If an IO error occurs. - */ - public static void main(String[] args) throws IOException { - -PrintStream oldOut = System.out; -PrintStream oldErr = System.err; -//PrintStream out = new PrintStream(new BufferedOutputStream(new FileOutputStream("C:/temp/rofutr.out"))); -//System.setOut(out); -//System.setErr(out); - - ASTFactory fact = new ASTFactory(); - //CompilationUnit cu = null; - - List toDo = new ArrayList(); - - if (args.length>0) { - toDo.add(new File(args[0])); - } - else { -//toDo.add(new File("C:\\java\\32\\jdk1.6.0_16\\src\\java\\util\\concurrent\\TimeUnit.java")); - File rootDir = new File("C:/java/32/jdk1.6.0_16/src/"); -//rootDir = new File("C:/dev/rsta/JavaAst/src"); -//rootDir = new File("C:/dev/rjava/Common/src"); - File[] files = rootDir.listFiles(); - for (int i=0; i - * - * You can get this tree automatically updating in response to edits in an - * RSyntaxTextArea with {@link JavaLanguageSupport} installed by - * calling {@link #listenTo(RSyntaxTextArea)}. Note that an instance of this - * class can only listen to a single editor at a time, so if your application - * contains multiple instances of RSyntaxTextArea, you'll either need a separate - * JavaOutlineTree for each one, or call uninstall() - * and listenTo(RSyntaxTextArea) each time a new RSTA receives - * focus. - * - * @author Robert Futrell - * @version 1.0 - */ -public class JavaOutlineTree extends AbstractSourceTree { - - private DefaultTreeModel model; - private RSyntaxTextArea textArea; - private JavaParser parser; - private Listener listener; - - - /** - * Constructor. The tree created will not have its elements sorted - * alphabetically. - */ - public JavaOutlineTree() { - this(false); - } - - - /** - * Constructor. - * - * @param sorted Whether the tree should sort its elements alphabetically. - * Note that outline trees will likely group nodes by type before - * sorting (i.e. methods will be sorted in one group, fields in - * another group, etc.). - */ - public JavaOutlineTree(boolean sorted) { - setSorted(sorted); - setBorder(BorderFactory.createEmptyBorder(0,8,0,8)); - setRootVisible(false); - setCellRenderer(new AstTreeCellRenderer()); - model = new DefaultTreeModel(new DefaultMutableTreeNode("Nothing")); - setModel(model); - listener = new Listener(); - addTreeSelectionListener(listener); - } - - - /** - * Refreshes this tree. - * - * @param cu The parsed compilation unit. If this is null - * then the tree is cleared. - */ - private void update(CompilationUnit cu) { - - JavaTreeNode root = new JavaTreeNode("Remove me!", - IconFactory.SOURCE_FILE_ICON); - root.setSortable(false); - if (cu==null) { - model.setRoot(root); - return; - } - - Package pkg = cu.getPackage(); - if (pkg!=null) { - String iconName = IconFactory.PACKAGE_ICON; - root.add(new JavaTreeNode(pkg, iconName, false)); - } - - if (!getShowMajorElementsOnly()) { - JavaTreeNode importNode = new JavaTreeNode("Imports", - IconFactory.IMPORT_ROOT_ICON); - Iterator i = cu.getImportIterator(); - while (i.hasNext()) { - ImportDeclaration idec = i.next(); - JavaTreeNode iNode = new JavaTreeNode(idec, - IconFactory.IMPORT_ICON); - importNode.add(iNode); - } - root.add(importNode); - } - - Iterator i = cu.getTypeDeclarationIterator(); - while (i.hasNext()) { - TypeDeclaration td = i.next(); - TypeDeclarationTreeNode dmtn = createTypeDeclarationNode(td); - root.add(dmtn); - } - - model.setRoot(root); - root.setSorted(isSorted()); - refresh(); - - } - - - /** - * Refreshes listeners on the text area when its syntax style changes. - */ - private void checkForJavaParsing() { - - // Remove possible listener on old Java parser (in case they're just - // changing syntax style AWAY from Java) - if (parser!=null) { - parser.removePropertyChangeListener( - JavaParser.PROPERTY_COMPILATION_UNIT, listener); - parser = null; - } - - // Get the Java language support (shared by all RSTA instances editing - // Java that were registered with the LanguageSupportFactory). - LanguageSupportFactory lsf = LanguageSupportFactory.get(); - LanguageSupport support = lsf.getSupportFor(JavaTokenRegistration.SYNTAX_STYLE); - JavaLanguageSupport jls = (JavaLanguageSupport)support; - - // Listen for re-parsing of the editor, and update the tree accordingly - parser = jls.getParser(textArea); - if (parser!=null) { // Should always be true - parser.addPropertyChangeListener( - JavaParser.PROPERTY_COMPILATION_UNIT, listener); - // Populate with any already-existing CompilationUnit - CompilationUnit cu = parser.getCompilationUnit(); - update(cu); - } - else { - update((CompilationUnit)null); // Clear the tree - } - - } - - - private MemberTreeNode createMemberNode(Member member) { - - MemberTreeNode node = null; - if (member instanceof CodeBlock) { - node = new MemberTreeNode((CodeBlock)member); - } - else if (member instanceof Field) { - node = new MemberTreeNode((Field)member); - } - else { - node = new MemberTreeNode((Method)member); - } - - CodeBlock body = null; - if (member instanceof CodeBlock) { - body = (CodeBlock)member; - } - else if (member instanceof Method) { - body = ((Method)member).getBody(); - } - - if (body!=null && !getShowMajorElementsOnly()) { - for (int i=0; i i = ncd.getMemberIterator(); - while (i.hasNext()) { - dmtn.add(createMemberNode(i.next())); - } - } - - else if (td instanceof NormalInterfaceDeclaration) { - NormalInterfaceDeclaration nid = (NormalInterfaceDeclaration)td; - for (int j=0; j i = nid.getMemberIterator(); - while (i.hasNext()) { - dmtn.add(createMemberNode(i.next())); - } - } - - return dmtn; - - } - - - /** - * {@inheritDoc} - */ - @Override - public void expandInitialNodes() { - - // First, collapse all rows. - int j=0; - while (jgetText(false), so - * we look nice with ToolTipTrees. - * - * @return A string representation of this tree node. - */ - @Override - public String toString() { - return getText(false); - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/tree/LocalVarTreeNode.java b/src/main/java/org/fife/rsta/ac/bsh/tree/LocalVarTreeNode.java deleted file mode 100644 index d739b461..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/tree/LocalVarTreeNode.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.tree; - -import org.fife.rsta.ac.bsh.IconFactory; -import org.fife.rsta.ac.bsh.rjc.ast.LocalVariable; -import org.fife.ui.autocomplete.Util; - - -/** - * Tree node for a local variable. - * - * @author Robert Futrell - * @version 1.0 - */ -class LocalVarTreeNode extends JavaTreeNode { - - private String text; - - - public LocalVarTreeNode(LocalVariable var) { - - super(var); - setIcon(IconFactory.get().getIcon(IconFactory.LOCAL_VARIABLE_ICON)); - setSortPriority(PRIORITY_LOCAL_VAR); - - StringBuilder sb = new StringBuilder(); - sb.append(""); - sb.append(var.getName()); - sb.append(" : "); - sb.append(""); - MemberTreeNode.appendType(var.getType(), sb); - text = sb.toString(); - } - - - @Override - public String getText(boolean selected) { - // Strip out HTML tags - return selected ? Util.stripHtml(text). - replaceAll("<", "<").replaceAll(">", ">") : text; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/tree/MemberTreeNode.java b/src/main/java/org/fife/rsta/ac/bsh/tree/MemberTreeNode.java deleted file mode 100644 index f65d8bf6..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/tree/MemberTreeNode.java +++ /dev/null @@ -1,195 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.tree; - -import javax.swing.Icon; - -import org.fife.rsta.ac.bsh.DecoratableIcon; -import org.fife.rsta.ac.bsh.IconFactory; -import org.fife.rsta.ac.bsh.rjc.ast.CodeBlock; -import org.fife.rsta.ac.bsh.rjc.ast.Field; -import org.fife.rsta.ac.bsh.rjc.ast.FormalParameter; -import org.fife.rsta.ac.bsh.rjc.ast.Method; -import org.fife.rsta.ac.bsh.rjc.lang.Modifiers; -import org.fife.rsta.ac.bsh.rjc.lang.Type; -import org.fife.ui.autocomplete.Util; - - -/** - * Tree node for a field or method. - * - * @author Robert Futrell - * @version 1.0 - */ -class MemberTreeNode extends JavaTreeNode { - - private String text; - - - public MemberTreeNode(CodeBlock cb) { - super(cb); - text = "" + cb.getName(); - IconFactory fact = IconFactory.get(); - Icon base = fact.getIcon(IconFactory.METHOD_PRIVATE_ICON); - DecoratableIcon di = new DecoratableIcon(base); - int priority = PRIORITY_METHOD; - if (cb.isStatic()) { - di.addDecorationIcon(fact.getIcon(IconFactory.STATIC_ICON)); - priority += PRIORITY_BOOST_STATIC; - } - setIcon(di); - setSortPriority(priority); - } - - - public MemberTreeNode(Field field) { - - super(field); - - Modifiers mods = field.getModifiers(); - String icon = null; - - if (mods==null) { - icon = IconFactory.FIELD_DEFAULT_ICON; - } - else if (mods.isPrivate()) { - icon = IconFactory.FIELD_PRIVATE_ICON; - } - else if (mods.isProtected()) { - icon = IconFactory.FIELD_PROTECTED_ICON; - } - else if (mods.isPublic()) { - icon = IconFactory.FIELD_PUBLIC_ICON; - } - else { - icon = IconFactory.FIELD_DEFAULT_ICON; - } - - StringBuilder sb = new StringBuilder(); - sb.append(""); - sb.append(field.getName()); - sb.append(" : "); - sb.append(""); - - appendType(field.getType(), sb); - text = sb.toString(); - int priority = PRIORITY_FIELD; - - IconFactory fact = IconFactory.get(); - Icon base = fact.getIcon(icon); - DecoratableIcon di = new DecoratableIcon(base); - di.setDeprecated(field.isDeprecated()); - if (mods!=null) { - if (mods.isStatic()) { - di.addDecorationIcon(fact.getIcon(IconFactory.STATIC_ICON)); - priority += PRIORITY_BOOST_STATIC; - } - if (mods.isFinal()) { - di.addDecorationIcon(fact.getIcon(IconFactory.FINAL_ICON)); - } - } - setIcon(di); - - setSortPriority(priority); - - } - - - public MemberTreeNode(Method method) { - - super(method); - - String icon = null; - int priority = PRIORITY_METHOD; - - Modifiers mods = method.getModifiers(); - if (mods==null) { - icon = IconFactory.METHOD_DEFAULT_ICON; - } - else if (mods.isPrivate()) { - icon = IconFactory.METHOD_PRIVATE_ICON; - } - else if (mods.isProtected()) { - icon = IconFactory.METHOD_PROTECTED_ICON; - } - else if (mods.isPublic()) { - icon = IconFactory.METHOD_PUBLIC_ICON; - } - else { - icon = IconFactory.METHOD_DEFAULT_ICON; - } - StringBuilder sb = new StringBuilder(); - sb.append(""); - sb.append(method.getName()); - sb.append('('); - int paramCount = method.getParameterCount(); - for (int i=0; i"); - appendType(method.getType(), sb); - } - - text = sb.toString(); - - IconFactory fact = IconFactory.get(); - Icon base = fact.getIcon(icon); - DecoratableIcon di = new DecoratableIcon(base); - di.setDeprecated(method.isDeprecated()); - if (mods!=null) { - if (mods.isAbstract()) { - di.addDecorationIcon(fact.getIcon(IconFactory.ABSTRACT_ICON)); - } - if (method.isConstructor()) { - di.addDecorationIcon(fact.getIcon(IconFactory.CONSTRUCTOR_ICON)); - priority = PRIORITY_CONSTRUCTOR; // Overrides previous value - } - if (mods.isStatic()) { - di.addDecorationIcon(fact.getIcon(IconFactory.STATIC_ICON)); - priority += PRIORITY_BOOST_STATIC; - } - if (mods.isFinal()) { - di.addDecorationIcon(fact.getIcon(IconFactory.FINAL_ICON)); - } - } - setIcon(di); - - setSortPriority(priority); - - } - - - static void appendType(Type type, StringBuilder sb) { - if (type!=null) { - String t = type.toString(); - t = t.replaceAll("<", "<"); - t = t.replaceAll(">", ">"); - sb.append(t); - } - } - - - @Override - public String getText(boolean selected) { - // Strip out HTML tags - return selected ? Util.stripHtml(text). - replaceAll("<", "<").replaceAll(">", ">") : text; - } - - -} \ No newline at end of file diff --git a/src/main/java/org/fife/rsta/ac/bsh/tree/TypeDeclarationTreeNode.java b/src/main/java/org/fife/rsta/ac/bsh/tree/TypeDeclarationTreeNode.java deleted file mode 100644 index bf5b7b1c..00000000 --- a/src/main/java/org/fife/rsta/ac/bsh/tree/TypeDeclarationTreeNode.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * 03/21/2010 - * - * Copyright (C) 2010 Robert Futrell - * robert_futrell at users.sourceforge.net - * http://fifesoft.com/rsyntaxtextarea - * - * This library is distributed under a modified BSD license. See the included - * RSTALanguageSupport.License.txt file for details. - */ -package org.fife.rsta.ac.bsh.tree; - -import javax.swing.Icon; - -import org.fife.rsta.ac.bsh.DecoratableIcon; -import org.fife.rsta.ac.bsh.IconFactory; -import org.fife.rsta.ac.bsh.rjc.ast.EnumDeclaration; -import org.fife.rsta.ac.bsh.rjc.ast.NormalClassDeclaration; -import org.fife.rsta.ac.bsh.rjc.ast.NormalInterfaceDeclaration; -import org.fife.rsta.ac.bsh.rjc.ast.TypeDeclaration; -import org.fife.rsta.ac.bsh.rjc.lang.Modifiers; - - -/** - * Tree node for type declarations. - * - * @author Robert Futrell - * @version 1.0 - */ -class TypeDeclarationTreeNode extends JavaTreeNode { - - - public TypeDeclarationTreeNode(TypeDeclaration typeDec) { - - super(typeDec); - //System.out.println("... " + typeDec); - String iconName = null; - int priority = PRIORITY_TYPE; - - if (typeDec instanceof NormalClassDeclaration) { - NormalClassDeclaration ncd = (NormalClassDeclaration)typeDec; - if (ncd.getModifiers()!=null) { - if (ncd.getModifiers().isPublic()) { - iconName = IconFactory.CLASS_ICON; - } - else if (ncd.getModifiers().isProtected()) { - iconName = IconFactory.INNER_CLASS_PROTECTED_ICON; - } - else if (ncd.getModifiers().isPrivate()) { - iconName = IconFactory.INNER_CLASS_PRIVATE_ICON; - } - else { - iconName = IconFactory.INNER_CLASS_DEFAULT_ICON; - } - } - else { -//System.out.println("... " + value); - iconName = IconFactory.DEFAULT_CLASS_ICON; - } - } - else if (typeDec instanceof NormalInterfaceDeclaration) { - NormalInterfaceDeclaration nid = (NormalInterfaceDeclaration)typeDec; - if (nid.getModifiers()!=null && nid.getModifiers().isPublic()) { - iconName = IconFactory.INTERFACE_ICON; - } - else { - iconName = IconFactory.DEFAULT_INTERFACE_ICON; - } - } - else if (typeDec instanceof EnumDeclaration) { - EnumDeclaration ed = (EnumDeclaration)typeDec; - if (ed.getModifiers()!=null) { - if (ed.getModifiers().isPublic()) { - iconName = IconFactory.ENUM_ICON; - } - else if (ed.getModifiers().isProtected()) { - iconName = IconFactory.ENUM_PROTECTED_ICON;; - } - else if (ed.getModifiers().isPrivate()) { - iconName = IconFactory.ENUM_PRIVATE_ICON; - } - else { - iconName = IconFactory.ENUM_DEFAULT_ICON; - } - } - else { - //System.out.println("... " + value); - iconName = IconFactory.ENUM_DEFAULT_ICON; - } - } - - IconFactory fact = IconFactory.get(); - Icon mainIcon = fact.getIcon(iconName); - - if (mainIcon==null) { // Unknown type ??? - System.out.println("*** " + typeDec); - } - else { - DecoratableIcon di = new DecoratableIcon(mainIcon); - di.setDeprecated(typeDec.isDeprecated()); - Modifiers mods = typeDec.getModifiers(); - if (mods!=null) { - if (mods.isAbstract()) { - di.addDecorationIcon(fact.getIcon(IconFactory.ABSTRACT_ICON)); - } - else if (mods.isFinal()) { - di.addDecorationIcon(fact.getIcon(IconFactory.FINAL_ICON)); - } - if (mods.isStatic()) { - di.addDecorationIcon(fact.getIcon(IconFactory.STATIC_ICON)); - priority = PRIORITY_BOOST_STATIC; - } - } - setIcon(di); - } - - setSortPriority(priority); - - } - - - @Override - public String getText(boolean selected) { - TypeDeclaration typeDec = (TypeDeclaration)getUserObject(); - //System.out.println("... " + typeDec); - return typeDec!=null ? typeDec.getName() : null; - } - - -} \ No newline at end of file diff --git a/src/main/resources/META-INF/services/org.fife.rsta.ac.LanguageSupportRegistration b/src/main/resources/META-INF/services/org.fife.rsta.ac.LanguageSupportRegistration index 1f350290..1ed18b59 100644 --- a/src/main/resources/META-INF/services/org.fife.rsta.ac.LanguageSupportRegistration +++ b/src/main/resources/META-INF/services/org.fife.rsta.ac.LanguageSupportRegistration @@ -4,7 +4,6 @@ org.fife.rsta.ac.groovy.GroovyLanguageRegistration org.fife.rsta.ac.jsp.JspLanguageRegistration org.fife.rsta.ac.less.LessLanguageRegistration org.fife.rsta.ac.js.JavaScriptLanguageRegistration -org.fife.rsta.ac.bsh.JavaLanguageRegistration org.fife.rsta.ac.c.CLanguageRegistration org.fife.rsta.ac.html.HtmlLanguageRegistration org.fife.rsta.ac.php.PhpLanguageRegistration From 4cc2342352629d6b57e7c5f69a5ebd9d18eae48b Mon Sep 17 00:00:00 2001 From: Matthew Aguirre Date: Thu, 17 Sep 2015 13:20:30 -0400 Subject: [PATCH 3/5] Moved from com.artistech to org.tros --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index ba846a9d..c1782bbf 100644 --- a/pom.xml +++ b/pom.xml @@ -1,7 +1,7 @@ 4.0.0 - com.artistech + org.tros languagesupport 2.5.8 jar @@ -62,12 +62,12 @@ - com.artistech + org.tros rsyntaxtextarea 2.5.8 - com.artistech + org.tros autocomplete 2.5.8 From 883b7773c33443ccd0229135e021de8b1b6a70f9 Mon Sep 17 00:00:00 2001 From: Matthew Aguirre Date: Thu, 17 Sep 2015 13:27:20 -0400 Subject: [PATCH 4/5] Removed 'public' from interface methods. --- .../java/org/fife/rsta/ac/LanguageSupportRegistration.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/fife/rsta/ac/LanguageSupportRegistration.java b/src/main/java/org/fife/rsta/ac/LanguageSupportRegistration.java index b7f55a03..8867bd02 100644 --- a/src/main/java/org/fife/rsta/ac/LanguageSupportRegistration.java +++ b/src/main/java/org/fife/rsta/ac/LanguageSupportRegistration.java @@ -11,7 +11,7 @@ */ public interface LanguageSupportRegistration { - public String getLanguage(); + String getLanguage(); - public String getLanguageSupportType(); + String getLanguageSupportType(); } From 459154fc02d6c287cc7d4b111bc7f822f87f7641 Mon Sep 17 00:00:00 2001 From: Matthew Aguirre Date: Sat, 19 Sep 2015 18:53:51 -0400 Subject: [PATCH 5/5] Changed Java version to 1.5 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index c1782bbf..78133d86 100644 --- a/pom.xml +++ b/pom.xml @@ -85,7 +85,7 @@ UTF-8 - 1.6 - 1.6 + 1.5 + 1.5 \ No newline at end of file