Skip to content

Commit

Permalink
Support string constants for embedded languages
Browse files Browse the repository at this point in the history
  • Loading branch information
BoykoAlex committed Feb 25, 2025
1 parent f0524b4 commit 5009808
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2024 Broadcom, Inc.
* Copyright (c) 2024, 2025 Broadcom, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
Expand All @@ -14,7 +14,10 @@
import java.util.List;

import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.FieldAccess;
import org.eclipse.jdt.core.dom.InfixExpression;
import org.eclipse.jdt.core.dom.QualifiedName;
import org.eclipse.jdt.core.dom.SimpleName;
import org.eclipse.jdt.core.dom.StringLiteral;
import org.eclipse.jdt.core.dom.TextBlock;

Expand Down Expand Up @@ -50,6 +53,15 @@ public static EmbeddedLanguageSnippet extractEmbeddedExpression(Expression value
}
}
return new CompositeEmbeddedLanguageSnippet(snippets);
} else if (valueExp instanceof SimpleName se) {
Object o = se.resolveConstantExpressionValue();
if (o instanceof String v) {
return new StringConstantLanguageSnippet(valueExp.getStartPosition(), v);
}
} else if (valueExp instanceof FieldAccess fa) {
return extractEmbeddedExpression(fa.getName());
} else if (valueExp instanceof QualifiedName qn) {
return extractEmbeddedExpression(qn.getName());
}
return null;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*******************************************************************************
* Copyright (c) 2025 Broadcom, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Broadcom, Inc. - initial API and implementation
*******************************************************************************/
package org.springframework.ide.vscode.boot.java.embedded.lang;

import java.util.Collections;
import java.util.List;

import org.springframework.ide.vscode.commons.util.text.IRegion;

public class StringConstantLanguageSnippet implements EmbeddedLanguageSnippet {

final private int offset;
final private String value;

public StringConstantLanguageSnippet(int offset, String value) {
this.offset = offset;
this.value = value;
}

@Override
public List<IRegion> toJavaRanges(IRegion range) {
return Collections.emptyList();
}

@Override
public int toJavaOffset(int offset) {
return this.offset;
}

@Override
public String getText() {
return value;
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2024 Broadcom, Inc.
* Copyright (c) 2024, 2025 Broadcom, Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
Expand Down Expand Up @@ -536,5 +536,121 @@ public interface OwnerRepository {

}

@Test
void ConcatenatedStringWithConstantQuery() throws Exception {
String source = """
package my.package
import org.springframework.data.jpa.repository.Query;
public interface OwnerRepository {
static final String Q = " test FROM Te";
@Query(value = "SELECT" +
" DIS" +
"TINCT" +
Q +
"st", nativeQuery = true)
void findByLastName();
}
""";

String uri = Paths.get(jp.getLocationUri()).resolve("src/main/resource/my/package/OwnerRepository.java").toUri()
.toASCIIString();
CompilationUnit cu = CompilationUnitCache.parse2(source.toCharArray(), uri, "OwnerRepository.java", jp);

assertThat(cu).isNotNull();

List<SemanticTokenData> tokens = computeTokens(cu);

SemanticTokenData token = tokens.get(0);
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("SELECT");
assertThat(token).isEqualTo(new SemanticTokenData(171, 177, "keyword", new String[0]));

token = tokens.get(1);
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("DIS");
assertThat(token).isEqualTo(new SemanticTokenData(185, 188, "keyword", new String[0]));

token = tokens.get(2);
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("TINCT");
assertThat(token).isEqualTo(new SemanticTokenData(195, 200, "keyword", new String[0]));

// token = tokens.get(3);
// assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("test");
// assertThat(token).isEqualTo(new SemanticTokenData(165, 169, "variable", new String[0]));
//
// token = tokens.get(4);
// assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("FROM");
// assertThat(token).isEqualTo(new SemanticTokenData(170, 174, "keyword", new String[0]));
//
// token = tokens.get(5);
// assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("Te");
// assertThat(token).isEqualTo(new SemanticTokenData(175, 177, "variable", new String[0]));

token = tokens.get(3);
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("st");
assertThat(token).isEqualTo(new SemanticTokenData(213, 215, "variable", new String[0]));

}

@Test
void ConcatenatedStringWithFieldAccessConstantQuery() throws Exception {
String source = """
package my.package
import org.springframework.data.jpa.repository.Query;
public interface OwnerRepository {
static class P {
static final String Q = " test FROM Te";
}
@Query(value = "SELECT" +
" DIS" +
"TINCT" +
P.Q +
"st", nativeQuery = true)
void findByLastName();
}
""";

String uri = Paths.get(jp.getLocationUri()).resolve("src/main/resource/my/package/OwnerRepository.java").toUri()
.toASCIIString();
CompilationUnit cu = CompilationUnitCache.parse2(source.toCharArray(), uri, "OwnerRepository.java", jp);

assertThat(cu).isNotNull();

List<SemanticTokenData> tokens = computeTokens(cu);

SemanticTokenData token = tokens.get(0);
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("SELECT");
assertThat(token).isEqualTo(new SemanticTokenData(194, 200, "keyword", new String[0]));

token = tokens.get(1);
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("DIS");
assertThat(token).isEqualTo(new SemanticTokenData(208, 211, "keyword", new String[0]));

token = tokens.get(2);
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("TINCT");
assertThat(token).isEqualTo(new SemanticTokenData(218, 223, "keyword", new String[0]));

// token = tokens.get(3);
// assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("test");
// assertThat(token).isEqualTo(new SemanticTokenData(165, 169, "variable", new String[0]));
//
// token = tokens.get(4);
// assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("FROM");
// assertThat(token).isEqualTo(new SemanticTokenData(170, 174, "keyword", new String[0]));
//
// token = tokens.get(5);
// assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("Te");
// assertThat(token).isEqualTo(new SemanticTokenData(175, 177, "variable", new String[0]));

token = tokens.get(3);
assertThat(source.substring(token.getStart(), token.getEnd())).isEqualTo("st");
assertThat(token).isEqualTo(new SemanticTokenData(238, 240, "variable", new String[0]));

}
}

0 comments on commit 5009808

Please sign in to comment.