Class Parser
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.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescription(package private) static classThe main compile error for the parser(package private) static interface(package private) static interface -
Field Summary
FieldsModifier and TypeFieldDescriptionprivate final ParseAnnotationother parser componentsprivate final ParseAttributeprivate ArrayList<AnnotationData> (package private) ClassDataprivate final ParseConstPool(package private) CodeAttr(package private) CFVersionprivate booleanprivate final ParseInstructionprivate ArrayList<AnnotationData> private ModuleAttrprivate ArrayList<AnnotationData> private Stringprivate Stringprotected ConstantPoolFields inherited from class ParseBase
debugFlag, environment, parser, scanner -
Constructor Summary
ConstructorsModifierConstructorDescriptionprotectedParser(JasmEnvironment environment, CFVersion cfVersion) Create a parser -
Method Summary
Modifier and TypeMethodDescriptionprivate voidcheckReferenceIndex(long 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 .... private intcountParams(ConstCell sigCell) Scan method's signature to determine the size of parameters.(package private) StringencodeClassString(String classname) private voidendClass()End classprivate voidEnd moduleprivate voidEnd package-info(package private) final ClassData[]longprivate voidprivate voidmatch(JasmTokens.Token open, JasmTokens.Token close) The match() method is used to quickly match opening brackets (ie: '(', '{', or '[') with their closing counterpart.private voidParse a BootstrapMethod entry individually.private voidParse a group of BootstrapMethod entries.private voidparseClass(int mod) Parse a class or interface declaration.private voidparseClasses(Consumer<ArrayList<ConstCell>> classesConsumer) Parse a list of classes belonging to the [NestMembers | PermittedSubclasses] entryprivate voidprivate voidparseClassRef(Consumer<ConstCell<?>> consumer) Parse class reference used by statements: this_class[:] (CPINDEX | STRING); super_class[:] (CPINDEX | STRING);private voidParse the class Signature entry.private void(package private) ConstCellparseConstantClassInfo(boolean uncond) (package private) ConstCell(package private) ConstCellprivate voidParse constant declarationprivate voidprivate voidparseField(int mod) Parse a field.(package private) voidParse an Jasm file.(package private) Stringprivate voidparseInnerClass(int mod) Parse an inner class.private voidparseInnerClass_s1(int mod, ConstCell nameCell, ConstCell innerClass, ConstCell outerClass) private voidparseInnerClass_s2(int mod, ConstCell nameCell, ConstCell innerClass, ConstCell outerClass) private voidparseInnerClass_s3(int mod, ConstCell nameCell, ConstCell innerClass, ConstCell outerClass) private voidparseInnerClassGroup(int mod) Parse a group of InnerClasses.(package private) IndexerParse a signed integer of size bytes long.private voidDetermines whether the JASM file is for a package-info class or for a module-info class.(package private) voidparseLocVarDef(OpcodeTables.Opcode opcode) Parse a local variable (type) presented in the form (var) index #name_index:#descriptor_index; [ (var) index name:descriptor; ] or (type) index #name_index:#signature_index; [ (type) index name:signature; ](package private) voidparseLocVarEnd(OpcodeTables.Opcode opcode) Parse The index (LOCAL_VARIABLE) into the local variable array of the instructions: either endvar LOCAL_VARIABLE; or endtype LOCAL_VARIABLE;(package private) IndexerParse 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;(package private) voidparseMapItem(DataVector map) private voidparseMethod(int mod) Parse a method.(package private) ConstCellParses a field or method reference for a method handle.private ConstCell<?> private voidparseModule(int mod) Parse a module declaration.private NameInfoParses a module name in a module statement(s)(package private) ConstCellParse an external name: CPINDEX, string, or identifier.(package private) voidparseNameAndType(DataVector fields) Parse a set of CONSTANT_NameAndType_info entries in the following forms: #id1, #id2, #idN; or fldS:"Ljava/lang/String;", fldS:"I", fldI:"I";private voidParse a NestHost entryprivate voidprivate StringThe source text file can be free form (newlines are considered blanks) and may contain Java-style commenting.private voidParse a SourceDebugExtension attributeprivate void(package private) ClassFileConst.SubTagParses a sub-tag value in a method handle.private NameInfoParses a package or type name in a module statement(s)(package private) IndexerparseUInt(int size) Parse an unsigned integer of size bytes long.private voidparseUtf8List(Consumer<ArrayList<ConstCell>> utf8Consumer) Valhalla specific Parse a list of Utf-8 belonging to the [LoadableDescriptors] entryprivate voidprivate voidpic_tracecreate(int mod, ConstCell nameCell, ConstCell innerClass, ConstCell outerClass) private StringprependPackage(String className, boolean uncond) private voidRecover after a syntax error in a field.private voidRecover after a syntax error in the file.scanList(Parser.Method scanMethod, Parser.NameSupplier target, String err, boolean onlyOneElement) 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;private intscanModifier(int mod) Parse the modifiers(package private) intprivate voidscanRequires(Consumer<ModuleContent.Dependence> action) Scans ModuleStatement: requires [transitive|static|mandated|synthetic] ModuleName ; Scans ModuleStatement: requires [transitive|static|mandated|synthetic] #ref ;private <T extends ModuleContent.TargetType>
voidscanStatement(BiConsumer<T, Set<ModuleContent.TargetType>> action, Parser.NameSupplier source, Parser.NameSupplier target, JasmTokens.Token startList, boolean emptyListAllowed, String err) Scans Module Statement(s): exports [mandated|synthetic] packageName [to ModuleName {, ModuleName}*] ; opens [mandated|synthetic] packageName [to ModuleName {, ModuleName}*] ; provides TypeName with TypeName {,typeName} ;private voidscanStatement(Consumer<ModuleContent.TargetType> action, String err) Scans ModuleStatement: uses TypeName;(package private) voidsetDebugFlags(boolean debugScanner, boolean debugMembers, boolean debugCP, boolean debugAnnot, boolean debugInstr, boolean debugAttribute) private voidthrowSyntaxError(String msgId) Methods inherited from class ParseBase
init, init, init, setDebugFlag, traceMethodInfoLn, traceMethodInfoLn, traceMethodInfoLn
-
Field Details
-
clsDataList
-
annotParser
other parser components -
cpParser
-
instrParser
-
attributeParser
-
pool
-
classData
ClassData classData -
currentCFV
CFVersion currentCFV -
curCodeAttr
CodeAttr curCodeAttr -
pkg
-
pkgPrefix
-
packageAnnotations
-
classAnnotations
-
memberAnnotations
-
explicitCP
private boolean explicitCP -
moduleAttribute
-
-
Constructor Details
-
Parser
Create a parser- Throws:
IOException
-
-
Method Details
-
setDebugFlags
void setDebugFlags(boolean debugScanner, boolean debugMembers, boolean debugCP, boolean debugAnnot, boolean debugInstr, boolean debugAttribute) -
encodeClassString
-
getPosition
public long getPosition() -
parseVersion
-
parseIdent
- Throws:
SyntaxError
-
parseLocVarDef
Parse a local variable (type) presented in the form (var) index #name_index:#descriptor_index; [ (var) index name:descriptor; ] or (type) index #name_index:#signature_index; [ (type) index name:signature; ]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 or the signature of a local variable in the source program
- Throws:
SyntaxError
-
parseLocVarRef
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
-
parseLocVarEnd
Parse The index (LOCAL_VARIABLE) into the local variable array of the instructions: either endvar LOCAL_VARIABLE; or endtype LOCAL_VARIABLE;- Throws:
SyntaxError
-
parseNameAndType
Parse a set of CONSTANT_NameAndType_info entries in the following forms: #id1, #id2, #idN; or fldS:"Ljava/lang/String;", fldS:"I", fldI:"I";- Parameters:
fields- is the list of fields that is populated with a newly scanned item- Throws:
SyntaxError- if any format errorIOException- if any input error
-
parseMapItem
- Throws:
SyntaxErrorIOException
-
parseName
Parse an external name: CPINDEX, string, or identifier.- Throws:
SyntaxError
-
parseMethodHandle
Parses a field or method reference for a method handle.- Throws:
SyntaxError
-
checkReferenceIndex
private void checkReferenceIndex(long 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 filedefaultTag- expected reference_index tag (Method or InterfaceMethod)defaultTag2- 2nd expected reference_index tag (Method or InterfaceMethod)
-
parseSubtag
Parses a sub-tag value in a method handle.- Throws:
SyntaxError
-
parseConstantPackageInfo
- Throws:
SyntaxError
-
parseConstantModuleInfo
- Throws:
SyntaxError
-
parseConstantClassInfo
- Throws:
SyntaxError
-
throwSyntaxError
- Throws:
SyntaxError
-
prependPackage
-
parseInt
Parse a signed integer of size bytes long. size = 1 or 2- Throws:
SyntaxError
-
parseUInt
Parse an unsigned integer of size bytes long. size = 1 or 2- Throws:
SyntaxError
-
parseConstDef
private void parseConstDef()Parse constant declaration -
scanModifier
-
scanModifiers
- Throws:
SyntaxError
-
parseField
-
countParams
Scan method's signature to determine the size of parameters.- Throws:
SyntaxError
-
parseMethod
Parse a method.- Throws:
SyntaxErrorIOException
-
parseCodeAttribute
- Throws:
IOException
-
parseThrowsClause
-
parseBootstrapMethodGroup
Parse a group of BootstrapMethod entries.BootstrapMethods { N: MethodHandle; ( Arguments: (ARG,)* ARG; )? }
- Throws:
SyntaxError
-
parseBootstrapMethod
Parse a BootstrapMethod entry individually.Two formats are supported: BootstrapMethod #METHODHANDLE (#ARG)*; BootstrapMethod #MH; { (#ARG,)* (ARG)? }
- Throws:
SyntaxError
-
parseMHCell
- Throws:
SyntaxError
-
parseClassSignature
Parse the class Signature entry.- Throws:
SyntaxError
-
parseClassRef
-
parseSourceFile
- Throws:
SyntaxError
-
parseSourceDebugExtension
Parse a SourceDebugExtension attribute- Throws:
SyntaxError
-
parseNestHost
-
parseClasses
Parse a list of classes belonging to the [NestMembers | PermittedSubclasses] entry- Throws:
SyntaxError
-
parseUtf8List
Valhalla specific Parse a list of Utf-8 belonging to the [LoadableDescriptors] entry- Throws:
SyntaxError
-
parseEnclosingMethod
private void parseEnclosingMethod() -
parseRecord
- Throws:
SyntaxError
-
parseInnerClassGroup
Parse a group of InnerClasses.- Parameters:
mod- inner_class_access_flags is ignored for a group of inner classes.- Throws:
SyntaxErrorIOException
-
parseInnerClass
Parse an inner class.- Parameters:
mod- inner_class_access_flags- Throws:
SyntaxErrorIOException
-
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
-
pic_error
private void pic_error() -
match
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 '(';
-
recoverField
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
-
parseClass
Parse a class or interface declaration.- Throws:
IOException
-
parseTypeName
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.
-
parseModuleName
Parses a module name in a module statement(s)- Returns:
- Pair Either Module name or CP Index for the module name.
-
parseModule
Parse a module declaration.- Throws:
IOException
-
scanRequires
Scans ModuleStatement: requires [transitive|static|mandated|synthetic] ModuleName ; Scans ModuleStatement: requires [transitive|static|mandated|synthetic] #ref ; -
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
- Throws:
IOException
-
recoverFile
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
-
parseJasmPackages
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. 1. File FILENAME or class file CLASSNAME takes the highest priority. This filename cannot be overridden. 2. Public class CLASSNAME { }– class name is CLASSNAME, and this CLASSNAME will be used to generate the filename (i.e., CLASSNAME.class). 3. this_class – The filename will be CLASSNAME.class, but the class name will be this_class. -
parseResultingFile
The source text file can be free form (newlines are considered blanks) and may contain Java-style commenting. The first line of a JASM file represents the name of the resulting file in the destination directory. This name does not affect the content of the resulting file. This line has two forms: file FILENAME; or classfile CLASSNAME; In the latter case, extension .class will be added to form FILENAME.- Throws:
IOException
-
initializeClassData
private void initializeClassData()
-