/******************************************************************************* * Copyright (c) 2015 Bruno Medeiros and other Contributors. * 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 * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Bruno Medeiros - initial API and implementation *******************************************************************************/ package mmrnmhrm.core.build; import java.nio.file.Path; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import dtool.dub.DubBuildOutputParser; import melnorme.lang.ide.core.EclipseCore; import melnorme.lang.ide.core.LangCore; import melnorme.lang.ide.core.operations.ToolMarkersHelper; import melnorme.lang.ide.core.operations.build.BuildManager; import melnorme.lang.ide.core.operations.build.BuildTarget; import melnorme.lang.ide.core.operations.build.BuildTargetOperation; import melnorme.lang.ide.core.operations.build.BuildTargetOperation.BuildOperationParameters; import melnorme.lang.ide.core.utils.EclipseUtils; import melnorme.lang.ide.core.utils.ResourceUtils; import melnorme.lang.tooling.bundle.BundleInfo; import melnorme.lang.tooling.common.SourceLineColumnRange; import melnorme.lang.tooling.common.ToolSourceMessage; import melnorme.lang.tooling.common.ops.IOperationMonitor; import melnorme.utilbox.collections.ArrayList2; import melnorme.utilbox.collections.Indexable; import melnorme.utilbox.core.CommonException; import melnorme.utilbox.misc.Location; import melnorme.utilbox.misc.PathUtil; import melnorme.utilbox.misc.StringUtil; import melnorme.utilbox.process.ExternalProcessHelper.ExternalProcessResult; import melnorme.utilbox.status.Severity; import mmrnmhrm.core.DeeCoreMessages; import mmrnmhrm.core.dub_model.DeeBundleModelManager; import mmrnmhrm.core.dub_model.DeeBundleModelManager.DeeBundleModel; import mmrnmhrm.core.engine.DeeToolManager; public class DeeBuildManager extends BuildManager { public static final String BuildType_Default = ""; public DeeBuildManager(DeeBundleModel bundleModel, DeeToolManager toolManager) { super(bundleModel, toolManager); } @Override public DeeToolManager getToolManager() { return (DeeToolManager) super.getToolManager(); } @Override protected void bundleProjectAddedOrModified(IProject project, BundleInfo newBundleInfo) { if(newBundleInfo.getBundleDesc().isResolved()) { // We ignore resolved description, because only unresolved ones have configuration info return; } super.bundleProjectAddedOrModified(project, newBundleInfo); } @Override protected Indexable<BuildType> getBuildTypes_do() { return ArrayList2.<BuildType>create( new DeeBuildType(BuildType_Default), new DeeBuildType(DubBuildType.UNITTEST.getBuildTypeString()) ); } /* ----------------- ----------------- */ protected class DeeBuildType extends BuildType { public DeeBuildType(String name) { super(name); } @Override public String getDefaultCommandArguments(BuildTarget bt) throws CommonException { ArrayList2<String> buildArgs = new ArrayList2<>(); String buildConfigName = bt.getBuildConfigName(); String dubBuildType = bt.getBuildTypeName(); buildArgs.add("build"); if(!buildConfigName.equals(BundleInfo.DEFAULT_CONFIGURATION)) { buildArgs.addElements("-c" , buildConfigName); } if(!dubBuildType.isEmpty()) { buildArgs.addElements("-b" , dubBuildType); } return StringUtil.collToString(buildArgs, " "); } @Override public BuildTargetOperation getBuildOperation(BuildOperationParameters buildOpParams) throws CommonException { return new DeeBuildTargetOperation(buildOpParams); } } public class DeeBuildTargetOperation extends BuildTargetOperation { public DeeBuildTargetOperation(BuildOperationParameters buildOpParams) { super(buildOpParams); } @Override protected void processBuildOutput(ExternalProcessResult processResult, IOperationMonitor om) throws CommonException { new DubBuildOutputParser<CommonException>() { @Override protected void processDubFailure(String dubErrorLine) throws CommonException { try { addDubFailureMarker(dubErrorLine); } catch(CoreException e) { throw EclipseUtils.createCommonException(e); } }; @Override protected void processCompilerError(String filePathStr, String startPosStr, String errorMsg) { Path filePath; try { filePath = PathUtil.createPath(filePathStr); } catch(CommonException e) { LangCore.logError("Invalid path for tool message: ", e); return; } try { addCompilerErrorMarker(filePath, startPosStr, errorMsg); } catch (CoreException e) { // log, but otherwise ignore & continue EclipseCore.logStatus(e); } } }.handleResult(processResult); } public void addDubFailureMarker(String dubErrorLine) throws CoreException { String errorMessage = dubErrorLine == null ? DeeCoreMessages.RunningDubBuild_Error : dubErrorLine; IMarker dubMarker = getProject().createMarker(DeeBundleModelManager.DUB_PROBLEM_ID); dubMarker.setAttribute(IMarker.MESSAGE, errorMessage); dubMarker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR); } protected void addCompilerErrorMarker(Path filePath, String startPosStr, String errorMsg) throws CoreException { int line = -1; int column = -1; int endLine = -1; int endColumn = -1; try { String lineStr = StringUtil.substringUntilMatch(startPosStr, ","); String columnStr = StringUtil.segmentAfterMatch(startPosStr, ","); line = Integer.valueOf(lineStr); column = Integer.valueOf(columnStr); } catch (NumberFormatException e) { } SourceLineColumnRange sourceLinePos = new SourceLineColumnRange(line, column, endLine, endColumn); ToolSourceMessage toolMessage = new ToolSourceMessage(filePath, sourceLinePos, Severity.ERROR, errorMsg); Location projectLocation; try { projectLocation = ResourceUtils.getProjectLocation2(project); } catch(CommonException e) { throw EclipseCore.createCoreException(e); } new ToolMarkersHelper(true).addErrorMarkers(toolMessage, projectLocation); } } }