/******************************************************************************* * Copyright (c) 2015, 2015 IBM Corporation and others. * 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 melnorme.lang.ide.ui.editor.structure; import static melnorme.utilbox.core.Assert.AssertNamespace.assertNotNull; import java.util.Optional; import org.eclipse.jface.text.IDocument; import org.eclipse.ui.texteditor.ITextEditor; import melnorme.lang.ide.core.LangCore; import melnorme.lang.ide.core.engine.SourceModelManager; import melnorme.lang.ide.core.engine.SourceModelManager.StructureInfo; import melnorme.lang.ide.core.engine.SourceModelManager.StructureModelRegistration; import melnorme.lang.ide.core.text.ISourceBufferExt; import melnorme.lang.ide.ui.editor.EditorSourceBuffer; import melnorme.lang.ide.ui.utils.operations.CalculateValueUIOperation; import melnorme.lang.tooling.LocationKey; import melnorme.lang.tooling.common.ops.IOperationMonitor; import melnorme.lang.tooling.structure.SourceFileStructure; import melnorme.lang.tooling.structure.StructureElement; import melnorme.utilbox.concurrency.OperationCancellation; import melnorme.utilbox.core.CommonException; import melnorme.utilbox.core.fntypes.Result; import melnorme.utilbox.misc.Location; public class GetUpdatedStructureUIOperation extends CalculateValueUIOperation<SourceFileStructure> { protected final SourceModelManager modelManager; protected final LocationKey locationKey; protected final IDocument document; public GetUpdatedStructureUIOperation(LocationKey locKey, IDocument document) { this(LangCore.getSourceModelManager(), locKey, document); } public GetUpdatedStructureUIOperation(SourceModelManager modelManager, LocationKey locKey, IDocument document) { super("Awaiting Structure Calculation"); this.modelManager = assertNotNull(modelManager); this.locationKey = assertNotNull(locKey); this.document = assertNotNull(document); } protected StructureInfo structureInfo; @Override public void doExecute() throws CommonException, OperationCancellation { StructureModelRegistration registration = modelManager.connectStructureUpdates(locationKey, document, (__) -> { }); structureInfo = registration.structureInfo; try { super.doExecute(); } finally { registration.dispose(); } } @Override protected void executeBackgroundOperation() throws CommonException, OperationCancellation { if(!structureInfo.isStale()) { Result<SourceFileStructure, CommonException> structureResult = structureInfo.getStoredData(); if(structureResult.isException()) { // TODO: retry computation if in error } // No need for background op result = structureResult.get(); return; } else { super.executeBackgroundOperation(); } } @Override protected SourceFileStructure doBackgroundValueComputation(IOperationMonitor om) throws OperationCancellation, CommonException { return structureInfo.awaitUpdatedData(om).get(); } @Override protected void handleComputationResult(SourceFileStructure result) throws CommonException { if(result == null) { throw new CommonException( "Could not retrieve source file structure for: " + structureInfo.getKey2().getLabel()); } } /* ----------------- helpers ----------------- */ public static SourceFileStructure run_GetUpdatedStructure_UserOperation(ISourceBufferExt sourceBuffer) { Optional<Location> location = sourceBuffer.getLocation_opt(); LocationKey key; if(location.isPresent()) { key = new LocationKey(location.get()); } else { key = new LocationKey(sourceBuffer.getKeyForCurrentInput(), "[Unlocated source buffer]"); } IDocument doc = sourceBuffer.getDocument(); // TODO: try to refactor out the need to for a IDocument GetUpdatedStructureUIOperation op = new GetUpdatedStructureUIOperation(key, doc); return op.executeAndGetHandledResult(); } public static SourceFileStructure run_GetUpdatedStructure(ITextEditor editor) { return run_GetUpdatedStructure_UserOperation(new EditorSourceBuffer(editor)); } public static StructureElement run_GetUpdatedStructureElementAt(AbstractLangStructureEditor editor, int offset) { SourceFileStructure sourceFileStructure = run_GetUpdatedStructure(editor); if(sourceFileStructure == null) { return null; // Note, possible error result has already been handled and reported to the user. } return sourceFileStructure.getStructureElementAt(offset); } }