Class Parser

java.lang.Object
org.openjdk.asmtools.jasm.ParseBase
org.openjdk.asmtools.jasm.Parser

class Parser extends ParseBase
This class is used to parse Jasm statements and expressions. The result is a parse tree.

This class implements an operator precedence parser. Errors are reported to the Environment object, if the error can't be resolved immediately, a SyntaxError exception is thrown.

Error recovery is implemented by catching Scanner.SyntaxError exceptions and discarding input scanner.tokens until an input token is reached that is possibly a legal continuation.

The parse tree that is constructed represents the input exactly (no rewrites to simpler forms). This is important if the resulting tree is to be used for code formatting in a programming environment. Currently, only documentation comments are retained.

A parser owns several components (scanner, constant-parser, instruction-parser, annotations-parser) to which it delegates certain parsing responsibilities. This parser contains functions to parse the overall form of a class, and any members (fields, methods, inner-classes).

Syntax errors, should always be caught inside the parser for error recovery.

  • Field Details

  • Constructor Details

  • Method Details

    • setDebugFlags

      void setDebugFlags(boolean debugScanner, boolean debugMembers, boolean debugCP, boolean debugAnnot, boolean debugInstr)
    • encodeClassString

      String encodeClassString(String classname)
    • getPosition

      public int getPosition()
    • parseVersion

      private void parseVersion()
    • parseIdent

      String parseIdent() throws SyntaxError
      Throws:
      SyntaxError
    • parseLocVarDef

      void parseLocVarDef() throws SyntaxError
      Parse a local variable presented in the form (var) index #name_index:#descriptor_index; [ (var) index name:descriptor; ]

      index - a valid index into the local variable array of the current frame. name - valid unqualified name denoting a local variable descriptor - a field descriptor which encodes the type of a local variable in the source program

      Throws:
      SyntaxError
    • parseLocVarRef

      Indexer parseLocVarRef() throws SyntaxError, IOException
      Parse The index (LOCAL_VARIABLE) into the local variable array of the instructions: [wide]aload, astore, fload, fstore, iload, istore, lload, lstore, dload, dstore LOCAL_VARIABLE; [wide]iinc LOCAL_VARIABLE, NUMBER;
      Throws:
      SyntaxError
      IOException
    • parseLocVarEnd

      void parseLocVarEnd() throws SyntaxError, IOException
      Parse The index (LOCAL_VARIABLE) into the local variable array of the instructions: endvar LOCAL_VARIABLE;
      Throws:
      SyntaxError
      IOException
    • parseMapItem

      void parseMapItem(DataVector map) throws SyntaxError, IOException
      Throws:
      SyntaxError
      IOException
    • parseName

      ConstCell parseName() throws SyntaxError
      Parse an external name: CPINDEX, string, or identifier.
      Throws:
      SyntaxError
    • parseMethodHandle

      ConstCell parseMethodHandle(ClassFileConst.SubTag subtag) throws SyntaxError
      Parses a field or method reference for method handle.
      Throws:
      SyntaxError
    • checkReferenceIndex

      private void checkReferenceIndex(int position, ClassFileConst.ConstType defaultTag, ClassFileConst.ConstType defaultTag2)
      Check the pair reference_kind:reference_index where reference_kind is any from: REF_invokeVirtual, REF_newInvokeSpecial, REF_invokeStatic, REF_invokeSpecial, REF_invokeInterface and reference_index is one of [Empty], Method or InterfaceMethod There are possible entries: ldc Dynamic REF_newInvokeSpecial:InterfaceMethod LdcConDyTwice."": ldc Dynamic REF_invokeInterface:LdcConDyTwice."": ldc Dynamic REF_newInvokeSpecial:Method LdcConDyTwice."": ldc MethodHandle REF_newInvokeSpecial:InterfaceMethod LdcConDyTwice."": ldc MethodHandle REF_invokeInterface:LdcConDyTwice."": ldc MethodHandle REF_newInvokeSpecial:Method LdcConDyTwice."": invokedynamic MethodHandle REF_invokeStatic:Method java/lang/invoke/StringConcatFactory.makeConcatWithConstants: invokedynamic MethodHandle REF_invokeStatic:java/lang/invoke/StringConcatFactory.makeConcatWithConstants ....
      Parameters:
      position - the position in a source file
      defaultTag - expected reference_index tag (Method or InterfaceMethod)
      defaultTag2 - 2nd expected reference_index tag (Method or InterfaceMethod)
    • parseSubtag

      ClassFileConst.SubTag parseSubtag() throws SyntaxError
      Parses a sub-tag value in method handle.
      Throws:
      SyntaxError
    • parseConstantPackageInfo

      ConstCell parseConstantPackageInfo() throws SyntaxError
      Throws:
      SyntaxError
    • parseConstantModuleInfo

      ConstCell parseConstantModuleInfo() throws SyntaxError
      Throws:
      SyntaxError
    • parseConstantClassInfo

      ConstCell parseConstantClassInfo(boolean uncond) throws SyntaxError
      Throws:
      SyntaxError
    • throwSyntaxError

      private void throwSyntaxError(String msgId) throws SyntaxError
      Throws:
      SyntaxError
    • prependPackage

      private String prependPackage(String className, boolean uncond)
    • parseInt

      Indexer parseInt(String opCode, int size) throws SyntaxError, IOException
      Parse a signed integer of size bytes long. size = 1 or 2
      Throws:
      SyntaxError
      IOException
    • parseUInt

      Indexer parseUInt(int size) throws SyntaxError, IOException
      Parse an unsigned integer of size bytes long. size = 1 or 2
      Throws:
      SyntaxError
      IOException
    • parseConstDef

      private void parseConstDef()
      Parse constant declaration
    • scanModifier

      private int scanModifier(int mod) throws SyntaxError
      Parse the modifiers
      Throws:
      SyntaxError
    • scanModifiers

      int scanModifiers() throws SyntaxError
      Throws:
      SyntaxError
    • parseField

      private void parseField(int mod) throws SyntaxError
      Parse a field.
      Throws:
      SyntaxError
    • countParams

      private int countParams(ConstCell sigCell) throws SyntaxError
      Scan method's signature to determine size of parameters.
      Throws:
      SyntaxError
    • parseMethod

      private void parseMethod(int mod) throws SyntaxError, IOException
      Parse a method.
      Throws:
      SyntaxError
      IOException
    • parseCPXBootstrapMethod

      private void parseCPXBootstrapMethod() throws SyntaxError
      Parse a (CPX based) BootstrapMethod entry.
      Throws:
      SyntaxError
    • parseClassSignature

      private void parseClassSignature() throws SyntaxError
      Parse the class Signature entry.
      Throws:
      SyntaxError
    • parseClassRef

      private void parseClassRef(Consumer<ConstCell<?>> consumer)
      Parse class reference used by statements: this_class[:] (CPINDEX | STRING); super_class[:] (CPINDEX | STRING);
    • parseSourceFile

      private void parseSourceFile() throws SyntaxError
      Throws:
      SyntaxError
    • parseSourceDebugExtension

      private void parseSourceDebugExtension() throws SyntaxError
      Parse a SourceDebugExtension attribute
      Throws:
      SyntaxError
    • parseNestHost

      private void parseNestHost() throws SyntaxError
      Parse a NestHost entry
      Throws:
      SyntaxError
    • parseClasses

      private void parseClasses(Consumer<ArrayList<ConstCell>> classesConsumer) throws SyntaxError
      Parse a list of classes belonging to the [NestMembers | PermittedSubclasses | Preload] entry
      Throws:
      SyntaxError
    • parseRecord

      private void parseRecord() throws SyntaxError
      Parse the Record entry
      Throws:
      SyntaxError
    • parseInnerClass

      private void parseInnerClass(int mod) throws SyntaxError, IOException
      Parse an inner class.
      Throws:
      SyntaxError
      IOException
    • parseInnerClass_s1

      private void parseInnerClass_s1(int mod, ConstCell nameCell, ConstCell innerClass, ConstCell outerClass) throws IOException
      Throws:
      IOException
    • parseInnerClass_s2

      private void parseInnerClass_s2(int mod, ConstCell nameCell, ConstCell innerClass, ConstCell outerClass) throws IOException
      Throws:
      IOException
    • parseInnerClass_s3

      private void parseInnerClass_s3(int mod, ConstCell nameCell, ConstCell innerClass, ConstCell outerClass) throws IOException
      Throws:
      IOException
    • pic_tracecreate

      private void pic_tracecreate(int mod, ConstCell nameCell, ConstCell innerClass, ConstCell outerClass)
    • pic_error

      private void pic_error()
    • match

      private void match(JasmTokens.Token open, JasmTokens.Token close) throws IOException
      The match() method is used to quickly match opening brackets (ie: '(', '{', or '[') with their closing counterpart. This is useful during error recovery.

      Scan to a matching '}', ']' or ')'. The current scanner.token must be a '{', '[' or '(';

      Throws:
      IOException
    • recoverField

      private void recoverField() throws SyntaxError, IOException
      Recover after a syntax error in a field. This involves discarding scanner.tokens until an EOF or a possible legal continuation is encountered.
      Throws:
      SyntaxError
      IOException
    • parseClass

      private void parseClass(int mod) throws IOException
      Parse a class or interface declaration.
      Throws:
      IOException
    • parseTypeName

      private NameInfo parseTypeName() throws IOException
      Parses a package or type name in a module statement(s)
      Returns:
      Pair Either Package/Type name or CP Index for this Package/Type name.
      Throws:
      IOException
    • parseModuleName

      private NameInfo parseModuleName() throws IOException
      Parses a module name in a module statement(s)
      Returns:
      Pair Either Module name or CP Index for the module name.
      Throws:
      IOException
    • parseModule

      private void parseModule(int mod) throws IOException
      Parse a module declaration.
      Throws:
      IOException
    • scanRequires

      private void scanRequires(Consumer<ModuleContent.Dependence> action) throws IOException
      Scans ModuleStatement: requires [transitive|static|mandated|synthetic] ModuleName ; Scans ModuleStatement: requires [transitive|static|mandated|synthetic] #ref ;
      Throws:
      IOException
    • scanStatement

      private <T extends ModuleContent.TargetType> void scanStatement(BiConsumer<T,Set<ModuleContent.TargetType>> action, Parser.NameSupplier source, Parser.NameSupplier target, JasmTokens.Token startList, boolean emptyListAllowed, String err) throws IOException
      Scans Module Statement(s): exports [mandated|synthetic] packageName [to ModuleName {, ModuleName}*] ; opens [mandated|synthetic] packageName [to ModuleName {, ModuleName}*] ; provides TypeName with TypeName {,typeName} ;
      Throws:
      IOException
    • scanStatement

      private void scanStatement(Consumer<ModuleContent.TargetType> action, String err) throws IOException
      Scans ModuleStatement: uses TypeName;
      Throws:
      IOException
    • scanList

      private HashSet<NameInfo> scanList(Parser.Method scanMethod, Parser.NameSupplier target, String err, boolean onlyOneElement) throws IOException
      Scans the "to" or "with" part of the following ModuleStatement: exports PackageName [to ModuleName {, ModuleName}] ;, opens PackageName [to ModuleName {, ModuleName}] ; provides TypeName with TypeName [,typeName] ; uses TypeName;

      : [ModuleName {, ModuleName}]; , [TypeName [,typeName]]; or TypeName;

      Throws:
      IOException
    • parseClassMembers

      private void parseClassMembers() throws IOException
      Throws:
      IOException
    • recoverFile

      private void recoverFile() throws IOException
      Recover after a syntax error in the file. This involves discarding scanner.tokens until an EOF or a possible legal continuation is encountered.
      Throws:
      IOException
    • endClass

      private void endClass()
      End class
    • endPackageInfo

      private void endPackageInfo()
      End package-info
    • endModule

      private void endModule()
      End module
    • getClassesData

      final ClassData[] getClassesData()
    • parseJasmPackages

      private void parseJasmPackages() throws IOException
      Determines whether the JASM file is for a package-info class or for a module-info class.

      creates the correct kind of ClassData accordingly.

      Throws:
      IOException - if any parse exception is met
    • parseFile

      void parseFile()
      Parse an Jasm file.
    • initializeClassData

      private void initializeClassData()