Skip to content

Commit

Permalink
Merge pull request #42291 from Dilhasha/compiler-plugin-params
Browse files Browse the repository at this point in the history
Add a data holder to store params between compilations
  • Loading branch information
azinneera authored Mar 17, 2024
2 parents e1bfdb1 + fe2a862 commit e3f5fc7
Show file tree
Hide file tree
Showing 21 changed files with 596 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com).
*
* WSO2 LLC. licenses this file to you 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 io.ballerina.projects;

import java.util.HashMap;
import java.util.Map;

/**
* A class that acts as the compiler plugin cache for a project.
*
* @since 2201.8.7
*/
public class CompilerPluginCache {

Map<String, Map<String, Object>> pluginMap;

/**
* Constructor to initialize plugin cache.
*/
public CompilerPluginCache() {
pluginMap = new HashMap<>();
}

/**
* Returns the user data for a particular compiler plugin.
*
* @param key compiler plugin id
* @return data holder map for the plugin
*/
public Map<String, Object> getData(String key) {
if (!pluginMap.containsKey(key)) {
pluginMap.put(key, new HashMap<>());
}
return pluginMap.get(key);
}

/**
* Adds a data holder map for a compiler plugin.
*
* @param key string fully qualified name of the compiler plugin
* @param value user data as a map
*/
public void putData(String key, Map<String, Object> value) {
this.pluginMap.put(key, value);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@
import io.ballerina.projects.plugins.completion.CompletionProvider;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* The default implementation of the {@code CompilerPluginContext}.
Expand All @@ -41,13 +43,18 @@ class CompilerPluginContextIml implements CompilerPluginContext {
private final List<CodeModifierManager.CodeModifierInfo> codeModifiers = new ArrayList<>();
private final List<CompilerLifecycleManager.LifecycleListenerInfo> lifecycleListeners = new ArrayList<>();
private final List<CodeAction> codeActions = new ArrayList<>();

private Map<String, Object> compilerPluginUserData = new HashMap();
private final List<CompletionProvider> completionProviders = new ArrayList<>();

CompilerPluginContextIml(CompilerPluginInfo compilerPluginInfo) {
this.compilerPluginInfo = compilerPluginInfo;
}

CompilerPluginContextIml(CompilerPluginInfo compilerPluginInfo, Map<String, Object> userData) {
this.compilerPluginInfo = compilerPluginInfo;
this.compilerPluginUserData = userData;
}

public void addCodeAnalyzer(CodeAnalyzer codeAnalyzer) {
codeAnalyzers.add(new CodeAnalyzerManager.CodeAnalyzerInfo(codeAnalyzer, compilerPluginInfo));
}
Expand Down Expand Up @@ -103,4 +110,8 @@ public List<CompletionProvider> completionProviders() {
public CompilerPluginInfo compilerPluginInfo() {
return compilerPluginInfo;
}

public Map<String, Object> userData() {
return this.compilerPluginUserData;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ static CompilerPluginManager from(PackageCompilation compilation) {
List<CompilerPluginInfo> compilerPlugins = loadEngagedCompilerPlugins(directDependencies);
List<CompilerPluginInfo> inBuiltCompilerPlugins = loadInBuiltCompilerPlugins(rootPkgNode.packageInstance());
compilerPlugins.addAll(inBuiltCompilerPlugins);
List<CompilerPluginContextIml> compilerPluginContexts = initializePlugins(compilerPlugins);
List<CompilerPluginContextIml> compilerPluginContexts = initializePlugins(compilerPlugins, compilation);
return new CompilerPluginManager(compilation, compilerPluginContexts);
}

Expand Down Expand Up @@ -189,12 +189,23 @@ private static List<Package> getDirectDependencies(ResolvedPackageDependency roo
.collect(Collectors.toList());
}

private static List<CompilerPluginContextIml> initializePlugins(List<CompilerPluginInfo> compilerPlugins) {
private static List<CompilerPluginContextIml> initializePlugins(List<CompilerPluginInfo> compilerPlugins,
PackageCompilation compilation) {
// Skip initialization if the compiler plugins are already initialized for the project
if (!compilation.packageContext().project().compilerPluginContexts().isEmpty()) {
return compilation.packageContext().project().compilerPluginContexts();
}
List<CompilerPluginContextIml> compilerPluginContexts = new ArrayList<>(compilerPlugins.size());
for (CompilerPluginInfo compilerPluginInfo : compilerPlugins) {
CompilerPluginContextIml pluginContext = new CompilerPluginContextIml(compilerPluginInfo);
CompilerPluginCache pluginCache =
compilation.packageContext().project().projectEnvironmentContext().environment().getService(
CompilerPluginCache.class);
CompilerPluginContextIml pluginContext = new CompilerPluginContextIml(compilerPluginInfo,
pluginCache.getData(compilerPluginInfo.compilerPlugin().getClass().getCanonicalName()));
initializePlugin(compilerPluginInfo, pluginContext);
compilerPluginContexts.add(pluginContext);
// Add the plugin context to context list in project
compilation.packageContext().project().compilerPluginContexts().add(pluginContext);
}
return compilerPluginContexts;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import org.wso2.ballerinalang.compiler.util.CompilerOptions;

import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;

Expand All @@ -40,6 +42,7 @@ public abstract class Project {
protected ProjectEnvironment projectEnvironment;
private final ProjectKind projectKind;
private Map<String, ToolContext> toolContextMap;
private List<CompilerPluginContextIml> compilerPluginContexts;

protected Project(ProjectKind projectKind,
Path projectPath,
Expand All @@ -48,6 +51,7 @@ protected Project(ProjectKind projectKind,
this.sourceRoot = projectPath;
this.buildOptions = buildOptions;
this.projectEnvironment = projectEnvironmentBuilder.build(this);
this.compilerPluginContexts = new ArrayList<>();
}

protected Project(ProjectKind projectKind,
Expand All @@ -57,6 +61,7 @@ protected Project(ProjectKind projectKind,
this.sourceRoot = projectPath;
this.projectEnvironment = projectEnvironmentBuilder.build(this);
this.buildOptions = BuildOptions.builder().build();
this.compilerPluginContexts = new ArrayList<>();
}

void setBuildOptions(BuildOptions buildOptions) {
Expand Down Expand Up @@ -152,4 +157,8 @@ protected Project resetPackage(Project project) {
public abstract Optional<Path> documentPath(DocumentId documentId);

public abstract void save();

List<CompilerPluginContextIml> compilerPluginContexts() {
return this.compilerPluginContexts;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
*/
package io.ballerina.projects.environment;

import io.ballerina.projects.CompilerPluginCache;
import io.ballerina.projects.internal.environment.BallerinaDistribution;
import io.ballerina.projects.internal.environment.BallerinaUserHome;
import io.ballerina.projects.internal.environment.DefaultEnvironment;
Expand Down Expand Up @@ -96,6 +97,7 @@ public Environment build() {
CompilerContext compilerContext = populateCompilerContext();
environment.addService(CompilerContext.class, compilerContext);
ballerinaDistribution.loadLangLibPackages(compilerContext, packageResolver);
environment.addService(CompilerPluginCache.class, new CompilerPluginCache());
return environment;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import io.ballerina.projects.plugins.codeaction.CodeAction;
import io.ballerina.projects.plugins.completion.CompletionProvider;

import java.util.Map;

/**
* This class can be used to add various compiler plugin tasks to the current compilation.
*
Expand Down Expand Up @@ -68,4 +70,11 @@ public interface CompilerPluginContext {
* @param completionProvider the {@link CompletionProvider} instance
*/
void addCompletionProvider(CompletionProvider completionProvider);

/**
* Returns user data for the compiler plugin.
*
* @return Map of user data as Map<String, Object>
*/
Map<String, Object> userData();
}
1 change: 1 addition & 0 deletions project-api/project-api-test/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ dependencies {
compilerPluginJar project(':project-api-test-artifact:log-creator-pkg-provided-code-modifier')
compilerPluginJar project(':project-api-test-artifact:log-creator-pkg-provided-code-generator')
compilerPluginJar project(':project-api-test-artifact:log-creator-pkg-provided-code-analyzer')
compilerPluginJar project(':project-api-test-artifact:pkg-provided-compiler-plugin-with-shared-data')

testRuntimeOnly project(":ballerina-lang-test")
balRt project(':ballerina-rt')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ public void init() {
"compiler_plugin_tests/log_creator_pkg_provided_code_generator_im");
BCompileUtil.compileAndCacheBala(
"compiler_plugin_tests/log_creator_pkg_provided_code_analyzer_im");
BCompileUtil.compileAndCacheBala(
"compiler_plugin_tests/pkg_provided_compiler_plugin_with_shared_data");
}

@Test
Expand Down Expand Up @@ -603,6 +605,26 @@ public void testRunCodeGenAndModifyPluginsMethod() {
"Invalid compiler plugin file logs after running code generators and modifiers");
}

@Test(description = "Test the usage of BuildContext as a data holder for compiler plugins")
public void testBuildContextForCompilerPlugins() {
Package currentPackage = loadPackage("shared_data_plugin");

// Run code modifiers
CodeModifierResult codeModifierResult = currentPackage.runCodeModifierPlugins();
Assert.assertEquals(codeModifierResult.reportedDiagnostics().diagnosticCount(), 2,
"Unexpected compilation diagnostics from modifier");
OUT.println("Diagnostics from modifier");
codeModifierResult.reportedDiagnostics().diagnostics().forEach(OUT::println);

// Get the compilation
PackageCompilation compilation = codeModifierResult.updatedPackage().get().getCompilation();
DiagnosticResult diagnosticResult = compilation.diagnosticResult();
OUT.println("Diagnostics from analyzer");
diagnosticResult.diagnostics().forEach(OUT::println);
Assert.assertEquals(diagnosticResult.diagnosticCount(), 0,
"Unexpected compilation diagnostic from analyzer");
}

private Package loadPackage(String path) {
Path projectDirPath = RESOURCE_DIRECTORY.resolve(path);
BuildProject buildProject = TestUtils.loadBuildProject(projectDirPath);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[package]
org = "foo"
name = "test_pkg"
version = "0.1.0"
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[plugin]
class = "io.context.plugins.CompilerPluginWithSharedData"

[[dependency]]
path = "../../../../../build/compiler-plugin-jars/pkg-provided-compiler-plugin-with-shared-data-1.0.0.jar"
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com).
//
// WSO2 LLC. licenses this file to you 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.

public function main() {
}

function foo() {
}

function bar() {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[package]
org = "shared_data"
name = "combined_plugin"
version = "0.1.0"
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com).
//
// WSO2 LLC. licenses this file to you 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.

import foo/test_pkg as _;

function func1() {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright (c) 2024, WSO2 LLC. (http://wso2.com).
*
* WSO2 LLC. licenses this file to you 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.
*/

apply from: "$rootDir/gradle/javaProject.gradle"

description = 'Compiler Plugin Tests - Plugin with BuildContext usage'
version = '1.0.0'

dependencies {
implementation project(':ballerina-lang')
implementation project(':ballerina-parser')
implementation project(':ballerina-tools-api')
}

ext.moduleName = 'io.context.plugins'

compileJava {
doFirst {
options.compilerArgs = ['--module-path', classpath.asPath,]
classpath = files()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<!--
~ Copyright (c) 2024, WSO2 LLC. (http://wso2.com).
~
~ WSO2 LLC. licenses this file to you 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.
-->
<FindBugsFilter>
<Match>
<Class name="io.context.plugins.SharedDataTestCodeAnalyzer"/>
<Bug pattern="EI_EXPOSE_REP2"/>
</Match>
<Match>
<Class name="io.context.plugins.SharedDataTestCodeModifier"/>
<Bug pattern="EI_EXPOSE_REP2"/>
</Match>
</FindBugsFilter>
Loading

0 comments on commit e3f5fc7

Please sign in to comment.