<commit_before>/*
 * Copyright 2000-2009 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.intellij.psi.impl.source.tree.java;

import com.intellij.codeInsight.daemon.JavaErrorMessages;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.Constants;
import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry;
import com.intellij.psi.impl.source.tree.LeafElement;
import com.intellij.psi.impl.source.tree.TreeElement;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.impl.source.tree.injected.StringLiteralEscaper;
import com.intellij.psi.templateLanguages.OuterLanguageElement;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.List;

public class PsiLiteralExpressionImpl extends ExpressionPsiElement implements PsiLiteralExpression,PsiLanguageInjectionHost, Constants {
  @NonNls private static final String QUOT = "&quot;";
  @NonNls private static final String HEXPREFIX = "0x";
  @NonNls private static final String HEXPREFIX2 = "0X";
  @NonNls private static final String LHEX_PREFIX = "0xl";

  public PsiLiteralExpressionImpl() {
    super(LITERAL_EXPRESSION);
  }

  public PsiType getType() {
    IElementType i = getFirstChildNode().getElementType();
    if (i == INTEGER_LITERAL) {
      return PsiType.INT;
    }
    if (i == LONG_LITERAL) {
      return PsiType.LONG;
    }
    if (i == FLOAT_LITERAL) {
      return PsiType.FLOAT;
    }
    if (i == DOUBLE_LITERAL) {
      return PsiType.DOUBLE;
    }
    if (i == CHARACTER_LITERAL) {
      return PsiType.CHAR;
    }
    if (i == STRING_LITERAL) {
      return PsiType.getJavaLangString(getManager(), getResolveScope());
    }
    if (i == TRUE_KEYWORD || i == FALSE_KEYWORD) {
      return PsiType.BOOLEAN;
    }
    if (i == NULL_KEYWORD) {
      return PsiType.NULL;
    }
    return null;
  }

  @NonNls private static final String _2_IN_63 = Long.toString(-1L << 63).substring(1);
  @NonNls private static final String _2_IN_31 = Long.toString(-1L << 31).substring(1);
  @NonNls private static final String _2_IN_63_L = _2_IN_63 + "l";

  public Object getValue() {
    String text = getFirstChildNode().getText();
    int textLength = text.length();
    IElementType i = getFirstChildNode().getElementType();
    if (i == INTEGER_LITERAL) {
      try {
        if (text.startsWith(HEXPREFIX) || text.startsWith(HEXPREFIX2)) {
          // should fit in 32 bits
          if (textLength <= 9) return Integer.valueOf(text.substring(2), 16);
          final Long value = parseDigits(text.substring(2), 4, 32);
          return value == null ? null : Integer.valueOf(value.intValue());
        }
        if (StringUtil.startsWithChar(text, '0')) {
          // should fit in 32 bits
          if (textLength <= 12) return Integer.valueOf(text, 8);
          final Long value = parseDigits(text, 3, 32);
          return value == null ? null : Integer.valueOf(value.intValue());
        }
        final long l = Long.parseLong(text, 10);
        if (text.equals(_2_IN_31)) return Integer.valueOf((int)l);
        long converted = (int)l;
        return l == converted ? Integer.valueOf((int)l) : null;
      }
      catch (Exception e) {
        return null;
      }
    }
    if (i == LONG_LITERAL) {
      if (StringUtil.endsWithChar(text, 'L') || StringUtil.endsWithChar(text, 'l')) {
        text = text.substring(0, textLength - 1);
        textLength = text.length();
      }
      try {
        if (text.startsWith(HEXPREFIX) || text.startsWith(HEXPREFIX2)) {
          if (textLength <= 17) return Long.valueOf(text.substring(2), 16);
          return parseDigits(text.substring(2), 4, 64);
        }
        if (StringUtil.startsWithChar(text, '0')) {
          // should fit in 64 bits
          if (textLength <= 23) return Long.valueOf(text, 8);
          return parseDigits(text, 3, 64);
        }
        if (_2_IN_63.equals(text)) return Long.valueOf(-1L << 63);
        return Long.valueOf(text, 10);
      }
      catch (Exception e) {
        return null;
      }
    }
    if (i == FLOAT_LITERAL) {
      try {
        return Float.valueOf(text);
      }
      catch (Exception e) {
        return null;
      }
    }
    if (i == DOUBLE_LITERAL) {
      try {
        return Double.valueOf(text);
      }
      catch (Exception e) {
        return null;
      }
    }
    if (i == CHARACTER_LITERAL) {
      if (StringUtil.endsWithChar(text, '\'')) {
        if (textLength == 1) return null;
        text = text.substring(1, textLength - 1);
      }
      else {
        text = text.substring(1, textLength);
      }
      StringBuilder chars = new StringBuilder();
      boolean success = parseStringCharacters(text, chars, null);
      if (!success) return null;
      if (chars.length() != 1) return null;
      return new Character(chars.charAt(0));
    }
    if (i == STRING_LITERAL) {
      if (StringUtil.endsWithChar(text, '\"')) {
        if (textLength == 1) return null;
        text = text.substring(1, textLength - 1);
      }
      else {
        if (text.startsWith(QUOT) && text.endsWith(QUOT) && textLength > QUOT.length()) {
          text = text.substring(QUOT.length(), textLength - QUOT.length());
        }
        else {
          return null;
        }
      }
      return internedParseStringCharacters(text);
    }
    if (i == TRUE_KEYWORD) {
      return Boolean.TRUE;
    }
    if (i == FALSE_KEYWORD) {
      return Boolean.FALSE;
    }
    if (i == NULL_KEYWORD) {
      return null;
    }
    return null;
  }

  // convert text to number according to radix specified
  // if number is more than maxbits bits long, return null
  private static Long parseDigits(String text, int bitsInRadix, int maxBits) {
    final int radix = 1 << bitsInRadix;
    int textLength = text.length();
    long integer = Long.parseLong(text.substring(0, textLength - 1), radix);
    final int lastDigit = Character.digit(text.charAt(textLength - 1), radix);
    if ((integer & (-1L << maxBits - 4)) != 0) return null;
    integer <<= bitsInRadix;
    integer |= lastDigit;
    return Long.valueOf(integer);
  }

  public String getParsingError() {
    final Object value = getValue();
    TreeElement firstChildNode = getFirstChildNode();
    String text = firstChildNode.getText();
    IElementType i = firstChildNode.getElementType();
    if (i == INTEGER_LITERAL) {
      text = text.toLowerCase();
      //literal 2147483648 may appear only as the operand of the unary negation operator -.
      if (!(text.equals(_2_IN_31)
            && getParent() instanceof PsiPrefixExpression
            && ((PsiPrefixExpression)getParent()).getOperationSign().getTokenType() == MINUS)) {
        if (text.equals(HEXPREFIX)) return JavaErrorMessages.message("hexadecimal.numbers.must.contain.at.least.one.hexadecimal.digit");
        if (value == null || text.equals(_2_IN_31)) {
          return JavaErrorMessages.message("integer.number.too.large");
        }
      }
    }
    else if (i == LONG_LITERAL) {
      text = text.toLowerCase();
      //literal 9223372036854775808L may appear only as the operand of the unary negation operator -.
      if (!(text.equals(_2_IN_63_L)
            && getParent() instanceof PsiPrefixExpression
            && ((PsiPrefixExpression)getParent()).getOperationSign().getTokenType() == MINUS)) {
        if (text.equals(HEXPREFIX) || text.equals(LHEX_PREFIX)) return JavaErrorMessages.message("hexadecimal.numbers.must.contain.at.least.one.hexadecimal.digit");
        if (value == null || text.equals(_2_IN_63_L)) {
          return JavaErrorMessages.message("long.number.too.large");
        }<commit_msg>IDEA-18617<commit_after>/*
 * Copyright 2000-2009 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.intellij.psi.impl.source.tree.java;

import com.intellij.codeInsight.daemon.JavaErrorMessages;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.Constants;
import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry;
import com.intellij.psi.impl.source.tree.LeafElement;
import com.intellij.psi.impl.source.tree.TreeElement;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.impl.source.tree.injected.StringLiteralEscaper;
import com.intellij.psi.templateLanguages.OuterLanguageElement;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.List;

public class PsiLiteralExpressionImpl extends ExpressionPsiElement implements PsiLiteralExpression,PsiLanguageInjectionHost, Constants {
  @NonNls private static final String QUOT = "&quot;";
  @NonNls private static final String HEXPREFIX = "0x";
  @NonNls private static final String HEXPREFIX2 = "0X";
  @NonNls private static final String LHEX_PREFIX = "0xl";

  public PsiLiteralExpressionImpl() {
    super(LITERAL_EXPRESSION);
  }

  public PsiType getType() {
    IElementType i = getFirstChildNode().getElementType();
    if (i == INTEGER_LITERAL) {
      return PsiType.INT;
    }
    if (i == LONG_LITERAL) {
      return PsiType.LONG;
    }
    if (i == FLOAT_LITERAL) {
      return PsiType.FLOAT;
    }
    if (i == DOUBLE_LITERAL) {
      return PsiType.DOUBLE;
    }
    if (i == CHARACTER_LITERAL) {
      return PsiType.CHAR;
    }
    if (i == STRING_LITERAL) {
      return PsiType.getJavaLangString(getManager(), getResolveScope());
    }
    if (i == TRUE_KEYWORD || i == FALSE_KEYWORD) {
      return PsiType.BOOLEAN;
    }
    if (i == NULL_KEYWORD) {
      return PsiType.NULL;
    }
    return null;
  }

  @NonNls private static final String _2_IN_63 = Long.toString(-1L << 63).substring(1);
  @NonNls private static final String _2_IN_31 = Long.toString(-1L << 31).substring(1);
  @NonNls private static final String _2_IN_63_L = _2_IN_63 + "l";

  public Object getValue() {
    String text = getFirstChildNode().getText();
    int textLength = text.length();
    IElementType i = getFirstChildNode().getElementType();
    if (i == INTEGER_LITERAL) {
      try {
        if (text.startsWith(HEXPREFIX) || text.startsWith(HEXPREFIX2)) {
          // should fit in 32 bits
          final long value = parseDigits(text.substring(2), 4, 32);
          return Integer.valueOf((int)value);
        }
        if (StringUtil.startsWithChar(text, '0')) {
          // should fit in 32 bits
          final long value = parseDigits(text, 3, 32);
          return Integer.valueOf((int)value);
        }
        final long l = Long.parseLong(text, 10);
        if (text.equals(_2_IN_31)) return Integer.valueOf((int)l);
        long converted = (int)l;
        return l == converted ? Integer.valueOf((int)l) : null;
      }
      catch (NumberFormatException e) {
        return null;
      }
    }
    if (i == LONG_LITERAL) {
      if (StringUtil.endsWithChar(text, 'L') || StringUtil.endsWithChar(text, 'l')) {
        text = text.substring(0, textLength - 1);
      }
      try {
        if (text.startsWith(HEXPREFIX) || text.startsWith(HEXPREFIX2)) {
          return parseDigits(text.substring(2), 4, 64);
        }
        if (StringUtil.startsWithChar(text, '0')) {
          // should fit in 64 bits
          return parseDigits(text, 3, 64);
        }
        if (_2_IN_63.equals(text)) return Long.valueOf(-1L << 63);
        return Long.valueOf(text, 10);
      }
      catch (NumberFormatException e) {
        return null;
      }
    }
    if (i == FLOAT_LITERAL) {
      try {
        return Float.valueOf(text);
      }
      catch (NumberFormatException e) {
        return null;
      }
    }
    if (i == DOUBLE_LITERAL) {
      try {
        return Double.valueOf(text);
      }
      catch (NumberFormatException e) {
        return null;
      }
    }
    if (i == CHARACTER_LITERAL) {
      if (StringUtil.endsWithChar(text, '\'')) {
        if (textLength == 1) return null;
        text = text.substring(1, textLength - 1);
      }
      else {
        text = text.substring(1, textLength);
      }
      StringBuilder chars = new StringBuilder();
      boolean success = parseStringCharacters(text, chars, null);
      if (!success) return null;
      if (chars.length() != 1) return null;
      return Character.valueOf(chars.charAt(0));
    }
    if (i == STRING_LITERAL) {
      if (StringUtil.endsWithChar(text, '\"')) {
        if (textLength == 1) return null;
        text = text.substring(1, textLength - 1);
      }
      else {
        if (text.startsWith(QUOT) && text.endsWith(QUOT) && textLength > QUOT.length()) {
          text = text.substring(QUOT.length(), textLength - QUOT.length());
        }
        else {
          return null;
        }
      }
      return internedParseStringCharacters(text);
    }
    if (i == TRUE_KEYWORD) {
      return Boolean.TRUE;
    }
    if (i == FALSE_KEYWORD) {
      return Boolean.FALSE;
    }
    if (i == NULL_KEYWORD) {
      return null;
    }
    return null;
  }

  // convert text to number according to radix specified
  // if number is more than maxbits bits long, throws NumberFormatException
  private static long parseDigits(String text, int bitsInRadix, int maxBits) throws NumberFormatException {
    final int radix = 1 << bitsInRadix;
    int textLength = text.length();
    if (textLength == 0) {
      throw new NumberFormatException(text);
    }
    long integer = textLength == 1 ? 0 : Long.parseLong(text.substring(0, textLength - 1), radix);
    if ((integer & (-1L << (maxBits - bitsInRadix))) != 0) {
      throw new NumberFormatException(text);
    }
    int lastDigit = Character.digit(text.charAt(textLength - 1), radix);
    if (lastDigit == -1) {
      throw new NumberFormatException(text);
    }
    integer <<= bitsInRadix;
    integer |= lastDigit;
    return integer;
  }

  public String getParsingError() {
    final Object value = getValue();
    TreeElement firstChildNode = getFirstChildNode();
    String text = firstChildNode.getText();
    IElementType i = firstChildNode.getElementType();
    if (i == INTEGER_LITERAL) {
      text = text.toLowerCase();
      //literal 2147483648 may appear only as the operand of the unary negation operator -.
      if (!(text.equals(_2_IN_31)
            && getParent() instanceof PsiPrefixExpression
            && ((PsiPrefixExpression)getParent()).getOperationSign().getTokenType() == MINUS)) {
        if (text.equals(HEXPREFIX)) return JavaErrorMessages.message("hexadecimal.numbers.must.contain.at.least.one.hexadecimal.digit");
        if (value == null || text.equals(_2_IN_31)) {
          return JavaErrorMessages.message("integer.number.too.large");
        }
      }
    }
    else if (i == LONG_LITERAL) {
      text = text.toLowerCase();
      //literal 9223372036854775808L may appear only as the operand of the unary negation operator -.
      if (!(text.equals(_2_IN_63_L)
            && getParent() instanceof PsiPrefixExpression
            && ((PsiPrefixExpression)getParent()).getOperationSign().getTokenType() == MINUS)) {
        if (text.equals(HEXPREFIX) || text.equals(LHEX_PREFIX)) return JavaErrorMessages.message("hexadecimal.numbers.must.contain.at.least.one.hexadecimal.digit");
        if (value == null || text.equals(_2_IN_63_L)) {
          return JavaErrorMessages.message("long.number.too.large");
        }
{'fraction_non_alphanumeric': 0.11965455628350208, 'fraction_numerical': 0.017093508040500298, 'mean_word_length': 2.8582261029411766, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2774224', 'n_tokens_mistral': 5398, 'n_tokens_neox': 5192, 'n_words': 1256}