Token.java revision 1489:6d9a3ef84ebf
150477Speter/* 235388Smjacob * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved. 335388Smjacob * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 435388Smjacob * 573319Smjacob * This code is free software; you can redistribute it and/or modify it 635388Smjacob * under the terms of the GNU General Public License version 2 only, as 735388Smjacob * published by the Free Software Foundation. Oracle designates this 835388Smjacob * particular file as subject to the "Classpath" exception as provided 935388Smjacob * by Oracle in the LICENSE file that accompanied this code. 1035388Smjacob * 1135388Smjacob * This code is distributed in the hope that it will be useful, but WITHOUT 1235388Smjacob * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1366189Smjacob * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1466189Smjacob * version 2 for more details (a copy is included in the LICENSE file that 1535388Smjacob * accompanied this code). 1635388Smjacob * 1735388Smjacob * You should have received a copy of the GNU General Public License version 1835388Smjacob * 2 along with this work; if not, write to the Free Software Foundation, 1935388Smjacob * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2035388Smjacob * 2135388Smjacob * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2235388Smjacob * or visit www.oracle.com if you need additional information or have any 2335388Smjacob * questions. 2435388Smjacob */ 2535388Smjacob 2635388Smjacobpackage jdk.nashorn.internal.parser; 2735388Smjacob 2835388Smjacobimport static jdk.nashorn.internal.parser.TokenKind.LITERAL; 2977365Smjacob 3077365Smjacobimport jdk.nashorn.internal.runtime.Source; 3164176Smjacob 3277365Smjacob/** 3377365Smjacob * Basic parse/lex unit. 3477365Smjacob * 3535388Smjacob */ 3675200Smjacobpublic class Token { 3777365Smjacob 3862498Smjacob private Token() { 3949915Smjacob } 4049915Smjacob 4162173Smjacob /** 4277365Smjacob * Create a compact form of token information. 4349915Smjacob * @param type Type of token. 4439235Sgibbs * @param position Start position of the token in the source. 4560220Smjacob * @param length Length of the token. 4677365Smjacob * @return Token descriptor. 4777365Smjacob */ 4877365Smjacob public static long toDesc(final TokenType type, final int position, final int length) { 4977365Smjacob return (long)position << 32 | 5077365Smjacob (long)length << 8 | 5177365Smjacob type.ordinal(); 5277365Smjacob } 5377365Smjacob 5477365Smjacob /** 5577365Smjacob * Extract token position from a token descriptor. 5677365Smjacob * @param token Token descriptor. 5777365Smjacob * @return Start position of the token in the source. 5877365Smjacob */ 5977365Smjacob public static int descPosition(final long token) { 6077365Smjacob return (int)(token >>> 32); 6177365Smjacob } 6277365Smjacob 6355371Smjacob /** 6449915Smjacob * Normally returns the token itself, except in case of string tokens 6539235Sgibbs * which report their position past their opening delimiter and thus 6642131Smjacob * need to have position and length adjusted. 6739235Sgibbs * 6846972Smjacob * @param token Token descriptor. 6939235Sgibbs * @return same or adjusted token. 7039235Sgibbs */ 7146972Smjacob public static long withDelimiter(final long token) { 7246972Smjacob final TokenType tokenType = Token.descType(token); 7339235Sgibbs switch(tokenType) { 7439235Sgibbs case STRING: 7546972Smjacob case ESCSTRING: 7639235Sgibbs case EXECSTRING: 7746972Smjacob case TEMPLATE: 7846972Smjacob case TEMPLATE_TAIL: { 7946972Smjacob final int start = Token.descPosition(token) - 1; 8046972Smjacob final int len = Token.descLength(token) + 2; 8146972Smjacob return toDesc(tokenType, start, len); 8246972Smjacob } 8346972Smjacob case TEMPLATE_HEAD: 8452349Smjacob case TEMPLATE_MIDDLE: { 8539235Sgibbs final int start = Token.descPosition(token) - 1; 8639235Sgibbs final int len = Token.descLength(token) + 3; 8739235Sgibbs return toDesc(tokenType, start, len); 8839235Sgibbs } 8939235Sgibbs default: { 9046972Smjacob return token; 9139235Sgibbs } 9279336Smjacob } 9346972Smjacob } 9473245Smjacob 9546972Smjacob /** 9639235Sgibbs * Extract token length from a token descriptor. 9779336Smjacob * @param token Token descriptor. 9839235Sgibbs * @return Length of the token. 9939235Sgibbs */ 10079336Smjacob public static int descLength(final long token) { 10162498Smjacob return (int)token >>> 8; 10262498Smjacob } 10362498Smjacob 10479336Smjacob /** 10562498Smjacob * Extract token type from a token descriptor. 10679336Smjacob * @param token Token descriptor. 10779336Smjacob * @return Type of token. 10869597Smjacob */ 10969597Smjacob public static TokenType descType(final long token) { 11062498Smjacob return TokenType.getValues()[(int)token & 0xff]; 11162498Smjacob } 11262498Smjacob 11346972Smjacob /** 11446972Smjacob * Change the token to use a new type. 11579336Smjacob * 11639235Sgibbs * @param token The original token. 11739235Sgibbs * @param newType The new token type. 11839235Sgibbs * @return The recast token. 11946972Smjacob */ 12039235Sgibbs public static long recast(final long token, final TokenType newType) { 12146972Smjacob return token & ~0xFFL | newType.ordinal(); 12246972Smjacob } 12377365Smjacob 12479336Smjacob /** 12539235Sgibbs * Return a string representation of a token. 12639235Sgibbs * @param source Token source. 12739235Sgibbs * @param token Token descriptor. 12846972Smjacob * @param verbose True to include details. 12939235Sgibbs * @return String representation. 13039235Sgibbs */ 13143420Smjacob public static String toString(final Source source, final long token, final boolean verbose) { 13246972Smjacob final TokenType type = Token.descType(token); 13339235Sgibbs String result; 13479336Smjacob 13546972Smjacob if (source != null && type.getKind() == LITERAL) { 13646972Smjacob result = source.getString(token); 13777365Smjacob } else { 13877365Smjacob result = type.getNameOrType(); 13977365Smjacob } 14077365Smjacob 14177365Smjacob if (verbose) { 14279336Smjacob final int position = Token.descPosition(token); 14379336Smjacob final int length = Token.descLength(token); 14477365Smjacob result += " (" + position + ", " + length + ")"; 14577365Smjacob } 14677365Smjacob 14777365Smjacob return result; 14877365Smjacob } 14977365Smjacob 15077365Smjacob /** 15179336Smjacob * String conversion of token 15279336Smjacob * 15377365Smjacob * @param source the source 15477365Smjacob * @param token the token 15579338Smjacob * 15677365Smjacob * @return token as string 15739235Sgibbs */ 15877365Smjacob public static String toString(final Source source, final long token) { 15946972Smjacob return Token.toString(source, token, false); 16046972Smjacob } 16146972Smjacob 16254671Smjacob /** 16379336Smjacob * String conversion of token - version without source given 16446972Smjacob * 16573245Smjacob * @param token the token 16646972Smjacob * 16746972Smjacob * @return token as string 16846972Smjacob */ 16946972Smjacob public static String toString(final long token) { 17077365Smjacob return Token.toString(null, token, false); 17146972Smjacob } 17246972Smjacob 17346972Smjacob /** 17446972Smjacob * Static hash code computation function token 17546972Smjacob * 17646972Smjacob * @param token a token 17777365Smjacob * 17879336Smjacob * @return hash code for token 17946972Smjacob */ 18046972Smjacob public static int hashCode(final long token) { 18146972Smjacob return (int)(token ^ token >>> 32); 18246972Smjacob } 18346972Smjacob 18446972Smjacob} 18546972Smjacob