Compilation reference of OpenJDK10: Compiling OpenJDK10 on WSL
Magic JAVA, add Chinese keywords, not much change, just change the source code of javac, which belong to java.compiler and jdk.compiler
Chinese key words, I used my own style, do not like, you can modify.
jdk10langtoolssrcjava.compilershareclassesjavaxlangmodelSourceVersion.java
Change the last function and add some judgment of Chinese Keywords:
public static boolean isKeyword(CharSequence s, SourceVersion version) { String id = s.toString(); switch(id) { // A trip through history case "strictfp": case "strict": return version.compareTo(RELEASE_2) >= 0; case "assert": case "break": return version.compareTo(RELEASE_4) >= 0; case "enum": case "lift": return version.compareTo(RELEASE_5) >= 0; case "_": return version.compareTo(RELEASE_9) >= 0; // Keywords common across versions // Modifiers case "public": case "protected": case "private": case "abstract": case "static": case "final": case "transient": case "volatile": case "synchronized": case "native": case "common": case "Protect": case "private": case "as": case "solid": case "end": case "temporary": case "easy": case "with": case "primary": // Declarations case "class": case "interface": case "extends": case "package": case "throws": case "implements": case "class": case "meet": case "Bear": case "package": case "Discard": case "become": // Primitive types and void case "boolean": case "byte": case "char": case "short": case "int": case "long": case "float": case "double": case "void": case "No two": case "word": case "symbol": case "short": case "whole": case "long": case "float": case "double": case "empty": // Control flow case "if": case "else": case "try": case "catch": case "finally": case "do": case "while": case "for": case "continue": case "switch": case "case": case "default": case "break": case "throw": case "return": case "as": case "another": case "try": case "catch": case "end": case "transport": case "When": case "by": case "Following": case "branch": case "example": case "Silent": case "broken": case "throw": case "return": // Other keywords case "this": case "new": case "super": case "import": case "instanceof": case "this": case "new": case "exceed": case "enter": case "yes": // Forbidden! case "goto": case "const": case "go": case "often": // literals case "null": case "true": case "false": case "nothing": case "really": case "false": return true; default: return false; }
jdk10langtoolssrcjdk.compilershareclassescomsuntoolsjavacparserTokens.java
Modify the Tokens class
public class Tokens { ... /** The names of all tokens. */ //private Name[] tokenName = new Name[TokenKind.values().length]; private Name[] tokenName = new Name[2 * TokenKind.values().length]; // Added Chinese keyword, length * 2 ... /* Original code protected Tokens(Context context) { context.put(tokensKey, this); names = Names.instance(context); for (TokenKind t : TokenKind.values()) { if (t.name != null) enterKeyword(t.name, t); else tokenName[t.ordinal()] = null; } key = new TokenKind[maxKey+1]; for (int i = 0; i <= maxKey; i++) key[i] = TokenKind.IDENTIFIER; for (TokenKind t : TokenKind.values()) { if (t.name != null) key[tokenName[t.ordinal()].getIndex()] = t; } } private void enterKeyword(String s, TokenKind token) { Name n = names.fromString(s); tokenName[token.ordinal()] = n; if (n.getIndex() > maxKey) maxKey = n.getIndex(); } */ protected Tokens(Context context) { context.put(tokensKey, this); names = Names.instance(context); for (TokenKind t : TokenKind.values()) { if (t.name != null) { Name n = names.fromString(t.name); tokenName[2 * t.ordinal()] = n; if (n.getIndex() > maxKey) maxKey = n.getIndex(); if (t.name_cn != null) { Name n_cn = names.fromString(t.name_cn); tokenName[2 * t.ordinal() + 1] = n_cn; if (n_cn.getIndex() > maxKey) maxKey = n_cn.getIndex(); } else { tokenName[2 * t.ordinal() + 1] = null; } } //enterKeyword(t.name, t); //It's not needed. It's rewritten else { tokenName[2 * t.ordinal()] = null; tokenName[2 * t.ordinal() + 1] = null; } } key = new TokenKind[maxKey+1]; for (int i = 0; i <= maxKey; i++) key[i] = TokenKind.IDENTIFIER; for (TokenKind t : TokenKind.values()) { if (t.name != null) { key[tokenName[2 * t.ordinal()].getIndex()] = t; if (t.name_cn != null) { key[tokenName[2 * t.ordinal() + 1].getIndex()] = t; } } } } } ... /** * This enum defines all tokens used by the javac scanner. A token is * optionally associated with a name. */ //Add Chinese keyword list, add a Chinese word after the English word // E.g. abstract ("abstract"), -- > Abstract ("abstract", "image"), // Assert ("assert", tag. Name), -- > assert ("assert", "break", tag. Name), // The specific implementation can be seen in the constructor at the end, which is relatively simple public enum TokenKind implements Formattable, Filter<TokenKind> { EOF(), ERROR(), IDENTIFIER(Tag.NAMED), ABSTRACT("abstract", "as"), ASSERT("assert", "break", Tag.NAMED), BOOLEAN("boolean", "No two", Tag.NAMED), BREAK("break", "broken"), BYTE("byte", "word", Tag.NAMED), CASE("case", "example"), CATCH("catch", "catch"), CHAR("char", "symbol", Tag.NAMED), CLASS("class", "class"), CONST("const", "often"), CONTINUE("continue", "Following"), DEFAULT("default", "Silent"), DO("do", "transport"), DOUBLE("double", "double", Tag.NAMED), ELSE("else", "another"), ENUM("enum", "lift", Tag.NAMED), EXTENDS("extends", "Bear"), FINAL("final", "end"), FINALLY("finally", "end"), FLOAT("float", "float", Tag.NAMED), FOR("for", "by"), GOTO("goto", "go"), IF("if", "as"), IMPLEMENTS("implements", "become"), IMPORT("import", "enter"), INSTANCEOF("instanceof", "yes"), INT("int", "whole", Tag.NAMED), INTERFACE("interface", "meet"), LONG("long", "long", Tag.NAMED), NATIVE("native", "primary"), NEW("new", "new"), PACKAGE("package", "package"), PRIVATE("private", "private"), PROTECTED("protected", "Protect"), PUBLIC("public", "common"), RETURN("return", "return"), SHORT("short", "short", Tag.NAMED), STATIC("static", "solid"), STRICTFP("strictfp", "strict"), SUPER("super", "exceed", Tag.NAMED), SWITCH("switch", "branch"), SYNCHRONIZED("synchronized", "with"), THIS("this", "this", Tag.NAMED), THROW("throw", "throw"), THROWS("throws", "Discard"), TRANSIENT("transient", "temporary"), TRY("try", "try"), VOID("void", "empty", Tag.NAMED), VOLATILE("volatile", "easy"), WHILE("while", "When"), INTLITERAL(Tag.NUMERIC), LONGLITERAL(Tag.NUMERIC), FLOATLITERAL(Tag.NUMERIC), DOUBLELITERAL(Tag.NUMERIC), CHARLITERAL(Tag.NUMERIC), STRINGLITERAL(Tag.STRING), TRUE("true", "really", Tag.NAMED), FALSE("false", "false", Tag.NAMED), NULL("null", "nothing", Tag.NAMED), UNDERSCORE("_", Tag.NAMED), ARROW("->"), COLCOL("::"), LPAREN("("), RPAREN(")"), LBRACE("{"), RBRACE("}"), LBRACKET("["), RBRACKET("]"), SEMI(";"), COMMA(","), DOT("."), ELLIPSIS("..."), EQ("="), GT(">"), LT("<"), BANG("!"), TILDE("~"), QUES("?"), COLON(":"), EQEQ("=="), LTEQ("<="), GTEQ(">="), BANGEQ("!="), AMPAMP("&&"), BARBAR("||"), PLUSPLUS("++"), SUBSUB("--"), PLUS("+"), SUB("-"), STAR("*"), SLASH("/"), AMP("&"), BAR("|"), CARET("^"), PERCENT("%"), LTLT("<<"), GTGT(">>"), GTGTGT(">>>"), PLUSEQ("+="), SUBEQ("-="), STAREQ("*="), SLASHEQ("/="), AMPEQ("&="), BAREQ("|="), CARETEQ("^="), PERCENTEQ("%="), LTLTEQ("<<="), GTGTEQ(">>="), GTGTGTEQ(">>>="), MONKEYS_AT("@"), CUSTOM; public final String name; public final String name_cn; //String of added Chinese keywords public final Tag tag; //Because the String of a Chinese keyword is added, the initialization is simple to modify TokenKind() { //this(null, Tag.DEFAULT); / / original code this(null, null, Tag.DEFAULT); //New code } TokenKind(String name) { //this(name, Tag.DEFAULT); / / original code this(name, null, Tag.DEFAULT); //New code } TokenKind(Tag tag) { //this(null, tag); / / original code this(null, null, tag); //New code } // The original constructor is changed to call the new one TokenKind(String name, Tag tag) { //this.name = name; //this.tag = tag; this(name, null, tag); } // Add new construction form TokenKind(String name, String name_cn) { //this.name = name; //this.tag = tag; this(name, name_cn, Tag.DEFAULT); } // Newly added constructor TokenKind(String name, String name_cn, Tag tag) { this.name = name; this.name_cn = name_cn; this.tag = tag; }
After the above two source files are modified, they are saved in UTF-8 format. Mainly, I prefer UTF-8 format. If you want to use other formats such as GBK, the following parameters, and Chinese source code, all match the same format.
After adding the code, the compilation parameters also need to be changed, because utf-8 characters are added to the source code to add the option of - encoding UTF-8 to java.compiler and jdk.compiler.
jdk10/make/CompileJavaModules.gmk line 88: java.compiler_ADD_JAVAC_FLAGS += -encoding UTF-8 -Xdoclint:all/protected '-Xdoclint/package:java.*,javax.*' line 354: jdk.compiler_ADD_JAVAC_FLAGS += -encoding UTF-8 -Xdoclint:all/protected '-Xdoclint/package:-com.sun.tools.*,-jdk.internal.*' \ -XDstringConcat=inline
After compiling, the following code can be compiled and printed successfully.
OpenJDK10 estimates that the default source code is UTF-8, so you do not need to add the - encoding UTF-8 parameter for compilation.
Package hello;
Public Hello{ main(String[] args){ System.out.println("Hello SwizL!"); } }
OpenJDK10 estimates that the default source code is UTF-8, so you do not need to add the - encoding UTF-8 parameter for compilation.
Reference resources: