1 /* <lambda>null2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.protolog.tool 18 19 import com.github.javaparser.ast.CompilationUnit 20 import com.github.javaparser.ast.ImportDeclaration 21 import com.github.javaparser.ast.expr.BinaryExpr 22 import com.github.javaparser.ast.expr.Expression 23 import com.github.javaparser.ast.expr.StringLiteralExpr 24 25 object CodeUtils { 26 /** 27 * Returns a stable hash of a string. 28 * We reimplement String::hashCode() for readability reasons. 29 */ 30 fun hash(position: String, messageString: String, logLevel: LogLevel, logGroup: LogGroup): Int { 31 return (position + messageString + logLevel.name + logGroup.name) 32 .map { c -> c.toInt() }.reduce { h, c -> h * 31 + c } 33 } 34 35 fun checkWildcardStaticImported(code: CompilationUnit, className: String, fileName: String) { 36 code.findAll(ImportDeclaration::class.java) 37 .forEach { im -> 38 if (im.isStatic && im.isAsterisk && im.name.toString() == className) { 39 throw IllegalImportException("Wildcard static imports of $className " + 40 "methods are not supported.", ParsingContext(fileName, im)) 41 } 42 } 43 } 44 45 fun isClassImportedOrSamePackage(code: CompilationUnit, className: String): Boolean { 46 val packageName = className.substringBeforeLast('.') 47 return code.packageDeclaration.isPresent && 48 code.packageDeclaration.get().nameAsString == packageName || 49 code.findAll(ImportDeclaration::class.java) 50 .any { im -> 51 !im.isStatic && 52 ((!im.isAsterisk && im.name.toString() == className) || 53 (im.isAsterisk && im.name.toString() == packageName)) 54 } 55 } 56 57 fun staticallyImportedMethods(code: CompilationUnit, className: String): Set<String> { 58 return code.findAll(ImportDeclaration::class.java) 59 .filter { im -> 60 im.isStatic && 61 im.name.toString().substringBeforeLast('.') == className 62 } 63 .map { im -> im.name.toString().substringAfterLast('.') }.toSet() 64 } 65 66 fun concatMultilineString(expr: Expression, context: ParsingContext): String { 67 return when (expr) { 68 is StringLiteralExpr -> expr.asString() 69 is BinaryExpr -> when { 70 expr.operator == BinaryExpr.Operator.PLUS -> 71 concatMultilineString(expr.left, context) + 72 concatMultilineString(expr.right, context) 73 else -> throw InvalidProtoLogCallException( 74 "expected a string literal " + 75 "or concatenation of string literals, got: $expr", context) 76 } 77 else -> throw InvalidProtoLogCallException("expected a string literal " + 78 "or concatenation of string literals, got: $expr", context) 79 } 80 } 81 } 82