From 93af9f33e46ed7cdfed19da886f921afe2ae14cc Mon Sep 17 00:00:00 2001 From: Vladimir Sukharev Date: Wed, 6 Dec 2023 09:56:58 +0100 Subject: [PATCH] Fix FqNameUnsafe.startsWith() when first segment of fqName is shorter than given segment FqNameUnsafe("c.C").startsWith("cnames") must return false It's a refix of fdf826208fbb5bfafc93e54abee52317fe6e462f --- .../kotlin/name/FqNameUnsafeTest.java | 50 +++++++++++++++++++ .../jetbrains/kotlin/name/FqNameUnsafe.java | 4 +- 2 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 compiler/tests/org/jetbrains/kotlin/name/FqNameUnsafeTest.java diff --git a/compiler/tests/org/jetbrains/kotlin/name/FqNameUnsafeTest.java b/compiler/tests/org/jetbrains/kotlin/name/FqNameUnsafeTest.java new file mode 100644 index 00000000000..eaf9a35a7f4 --- /dev/null +++ b/compiler/tests/org/jetbrains/kotlin/name/FqNameUnsafeTest.java @@ -0,0 +1,50 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.name; + +import org.junit.Assert; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class FqNameUnsafeTest { + @Test + public void pathSegments() { + Assert.assertEquals(new ArrayList(), new FqNameUnsafe("").pathSegments()); + + for (String name : new String[] { "org", "org.jetbrains", "org.jetbrains.kotlin" }) { + List segments = new FqNameUnsafe(name).pathSegments(); + List segmentsStrings = new ArrayList<>(); + for (Name segment : segments) { + segmentsStrings.add(segment.asString()); + } + Assert.assertEquals(Arrays.asList(name.split("\\.")), segmentsStrings); + } + } + + @Test + public void startsWithName() { + Assert.assertTrue(new FqNameUnsafe("abc.def").startsWith(Name.identifier("abc"))); + Assert.assertTrue(new FqNameUnsafe("abc").startsWith(Name.identifier("abc"))); + Assert.assertTrue(new FqNameUnsafe("abc.").startsWith(Name.identifier("abc"))); + Assert.assertTrue(new FqNameUnsafe(".abc").startsWith(Name.identifier(""))); + + Assert.assertFalse(new FqNameUnsafe("").startsWith(Name.identifier(""))); + Assert.assertFalse(new FqNameUnsafe("").startsWith(Name.identifier("id"))); + + Assert.assertFalse(new FqNameUnsafe("segment").startsWith(Name.identifier(""))); + Assert.assertFalse(new FqNameUnsafe("abc.").startsWith(Name.identifier("abc."))); + Assert.assertFalse(new FqNameUnsafe(".abc").startsWith(Name.identifier("abc"))); + Assert.assertFalse(new FqNameUnsafe(".abc").startsWith(Name.identifier("."))); + Assert.assertFalse(new FqNameUnsafe(".abc").startsWith(Name.identifier(".abc"))); + Assert.assertFalse(new FqNameUnsafe("abc.def").startsWith(Name.identifier("abc.def"))); + Assert.assertFalse(new FqNameUnsafe("abcdef").startsWith(Name.identifier("abc"))); + Assert.assertFalse(new FqNameUnsafe("abc").startsWith(Name.identifier("abcdef"))); + Assert.assertFalse(new FqNameUnsafe("abc.xyz").startsWith(Name.identifier("abcdef"))); + } +} diff --git a/core/compiler.common/src/org/jetbrains/kotlin/name/FqNameUnsafe.java b/core/compiler.common/src/org/jetbrains/kotlin/name/FqNameUnsafe.java index 4833d702133..e9234f3b488 100644 --- a/core/compiler.common/src/org/jetbrains/kotlin/name/FqNameUnsafe.java +++ b/core/compiler.common/src/org/jetbrains/kotlin/name/FqNameUnsafe.java @@ -163,8 +163,10 @@ public final class FqNameUnsafe { return false; int firstDot = fqName.indexOf('.'); + int fqNameFirstSegmentLength = firstDot == -1 ? fqName.length() : firstDot; String segmentAsString = segment.asString(); - return fqName.regionMatches(0, segmentAsString, 0, firstDot == -1 ? Math.max(fqName.length(), segmentAsString.length()) : firstDot); + return fqNameFirstSegmentLength == segmentAsString.length() && + fqName.regionMatches(0, segmentAsString, 0, fqNameFirstSegmentLength); } public boolean startsWith(@NotNull FqNameUnsafe other) {