tracefw/tracecompiler/src/com.nokia.tracecompiler/src/com/nokia/tracecompiler/engine/rules/AutoAddFunctionParametersRule.java
branchRCL_3
changeset 20 ca8a1b6995f6
equal deleted inserted replaced
19:07b41fa8d1dd 20:ca8a1b6995f6
       
     1 /*
       
     2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 * Trace rule for automatically adding function parameters to a trace
       
    17 *
       
    18 */
       
    19 package com.nokia.tracecompiler.engine.rules;
       
    20 
       
    21 import java.util.ArrayList;
       
    22 
       
    23 import com.nokia.tracecompiler.engine.TraceCompilerEngineErrorMessages;
       
    24 import com.nokia.tracecompiler.engine.TraceCompilerEngineGlobals;
       
    25 import com.nokia.tracecompiler.engine.TraceCompilerEngineErrorCodes.StringErrorParameters;
       
    26 import com.nokia.tracecompiler.engine.TraceCompilerEngineErrorCodes.TraceCompilerErrorCode;
       
    27 import com.nokia.tracecompiler.engine.header.ComplexHeaderRule;
       
    28 import com.nokia.tracecompiler.engine.source.TraceParameterFormattingRule;
       
    29 import com.nokia.tracecompiler.model.Trace;
       
    30 import com.nokia.tracecompiler.model.TraceCompilerException;
       
    31 import com.nokia.tracecompiler.model.TraceConstantTable;
       
    32 import com.nokia.tracecompiler.model.TraceObjectRuleCreateObject;
       
    33 import com.nokia.tracecompiler.model.TraceObjectRuleRemoveOnCreate;
       
    34 import com.nokia.tracecompiler.model.TraceParameter;
       
    35 import com.nokia.tracecompiler.source.SourceConstants;
       
    36 import com.nokia.tracecompiler.source.SourceContext;
       
    37 import com.nokia.tracecompiler.source.SourceParameter;
       
    38 import com.nokia.tracecompiler.source.SourceParserException;
       
    39 import com.nokia.tracecompiler.source.SourceUtils;
       
    40 import com.nokia.tracecompiler.source.TypeMapping;
       
    41 
       
    42 /**
       
    43  * Trace rule for automatically adding function parameters to a trace
       
    44  * 
       
    45  */
       
    46 public final class AutoAddFunctionParametersRule extends RuleBase implements
       
    47 		TraceObjectRuleCreateObject, TraceObjectRuleRemoveOnCreate {
       
    48 
       
    49 	/**
       
    50 	 * Warning about value-to-pointer conversion
       
    51 	 */
       
    52 	private static final String VALUE_TO_POINTER_WARNING = Messages
       
    53 			.getString("AutoAddFunctionParametersRule.UnrecognizedTypeWarning"); //$NON-NLS-1$
       
    54 
       
    55 	/*
       
    56 	 * (non-Javadoc)
       
    57 	 * 
       
    58 	 * @see
       
    59 	 * com.nokia.tracecompiler.model.TraceObjectRuleCreateObject#createObject()
       
    60 	 */
       
    61 	public void createObject() throws TraceCompilerException {
       
    62 		SourceContext context = TraceCompilerEngineGlobals.getSourceContextManager()
       
    63 				.getContext();
       
    64 		Trace trace = (Trace) getOwner();
       
    65 		if (context != null) {
       
    66 			boolean valid = false;
       
    67 			ArrayList<SourceParameter> list = tokenizeParameters(context);
       
    68 
       
    69 			trace.getModel().startProcessing();
       
    70 			try {
       
    71 				createParameters(trace, list);
       
    72 			} finally {
       
    73 				trace.getModel().processingComplete();
       
    74 			}
       
    75 			// At least one parameter must be parsed from source except for function entry extension
       
    76 			valid = trace.getParameterCount() > 0 || trace.getExtension(EntryTraceRule.class) != null;
       
    77 
       
    78 			if (!valid) {
       
    79 				String msg = TraceCompilerEngineErrorMessages.getErrorMessage(
       
    80 						TraceCompilerErrorCode.CANNOT_PARSE_FUNCTION_PARAMETERS,
       
    81 						null);
       
    82 				TraceCompilerEngineGlobals.getEvents().postWarningMessage(msg, trace);
       
    83 				// Removes the complex rule -> Function is not generated and
       
    84 				// source does not compile
       
    85 				trace.removeExtensions(ComplexHeaderRule.class);
       
    86 			}
       
    87 		} else {
       
    88 			String msg = TraceCompilerEngineErrorMessages.getErrorMessage(
       
    89 					TraceCompilerErrorCode.NO_CONTEXT_FOR_LOCATION, null);
       
    90 			TraceCompilerEngineGlobals.getEvents().postErrorMessage(msg, null, true);
       
    91 			// Removes the complex rule -> Function is not generated and
       
    92 			// source does not compile
       
    93 			trace.removeExtensions(ComplexHeaderRule.class);
       
    94 		}
       
    95 	}
       
    96 
       
    97 	/**
       
    98 	 * Creates the parameters to the trace
       
    99 	 * 
       
   100 	 * @param owner
       
   101 	 *            the trace
       
   102 	 * @param list
       
   103 	 *            the parameter list parsed from source
       
   104 	 * @throws TraceCompilerException 
       
   105 	 */
       
   106 	private void createParameters(Trace owner, ArrayList<SourceParameter> list) throws TraceCompilerException {
       
   107 
       
   108 		// If any of the parameters is "...", clear the whole parameter list
       
   109 		for (SourceParameter param : list) {
       
   110 			String type = param.getType();
       
   111 			if (type != null
       
   112 					&& type.equals(SourceConstants.VARIABLE_ARG_LIST_INDICATOR)) {
       
   113 				list.clear();
       
   114 				
       
   115 				
       
   116 				String msg = TraceCompilerEngineErrorMessages.getErrorMessage(
       
   117 						TraceCompilerErrorCode.VAR_ARG_LIST_PARAMETER_FOUND,
       
   118 						null);
       
   119 				TraceCompilerEngineGlobals.getEvents().postWarningMessage(msg, owner);
       
   120 				break;
       
   121 			}
       
   122 		}
       
   123 
       
   124 		StringBuilder str = new StringBuilder();
       
   125 		for (SourceParameter param : list) {
       
   126 			TraceParameter parameter = createParameter(owner, param);
       
   127 			if (parameter != null) {
       
   128 				str.append(SourceConstants.PARAMETER_SEPARATOR);
       
   129 				TraceParameterFormattingRule rule = parameter
       
   130 						.getExtension(TraceParameterFormattingRule.class);
       
   131 				if (rule != null) {
       
   132 					str.append(rule.mapNameToSource(param.getName()));
       
   133 				} else {
       
   134 					str.append(param.getName());
       
   135 				}
       
   136 			}
       
   137 			// The location will be referenced by event handlers if
       
   138 			// they need it. Otherwise it will be removed from the
       
   139 			// source
       
   140 			param.getSourceLocation().dereference();
       
   141 		}
       
   142 		// The header extension is stored in case of complex function entry
       
   143 		// trace
       
   144 		EntryTraceRule entryRule = owner.getExtension(EntryTraceRule.class);
       
   145 		ComplexHeaderRuleImpl complex = owner
       
   146 				.getExtension(ComplexHeaderRuleImpl.class);
       
   147 		if (entryRule != null && complex != null) {
       
   148 			complex.setTraceIDDefineExtension(str.toString());
       
   149 		}
       
   150 	}
       
   151 
       
   152 	/**
       
   153 	 * Processes the parameters of given source context
       
   154 	 * 
       
   155 	 * @param context
       
   156 	 *            the context
       
   157 	 * @return list of parameters
       
   158 	 * @throws TraceCompilerException 
       
   159 	 */
       
   160 	private ArrayList<SourceParameter> tokenizeParameters(SourceContext context) throws TraceCompilerException {
       
   161 		ArrayList<SourceParameter> list = new ArrayList<SourceParameter>();
       
   162 		try {
       
   163 			context.parseParameters(list);
       
   164 		} catch (SourceParserException e) {
       
   165 			TraceCompilerException exception = new TraceCompilerException(
       
   166 					TraceCompilerErrorCode.UNEXPECTED_EXCEPTION, e);
       
   167 			TraceCompilerEngineGlobals.getEvents().postError(
       
   168 					exception);
       
   169 			list = null;
       
   170 		}
       
   171 		return list;
       
   172 	}
       
   173 
       
   174 	/**
       
   175 	 * Creates a TraceParameter based on parameter parsed from source
       
   176 	 * 
       
   177 	 * @param owner
       
   178 	 *            the owning trace object
       
   179 	 * @param param
       
   180 	 *            the parameter found from source
       
   181 	 * @return the parameter
       
   182 	 */
       
   183 	private TraceParameter createParameter(Trace owner, SourceParameter param) {
       
   184 		TraceConstantTable foundTable = RuleUtils.findConstantTableByType(owner
       
   185 				.getModel(), param);
       
   186 		TraceParameter parameter = null;
       
   187 		if (foundTable == null) {
       
   188 			TypeMapping type = SourceUtils.mapSymbianTypeToParameterType(param);
       
   189 			if (type != null) {
       
   190 				if (!type.isVoid()) {
       
   191 					parameter = createParameter(owner, param, type);
       
   192 				}
       
   193 			} else {
       
   194 				StringErrorParameters params = new StringErrorParameters();
       
   195 				params.string = param.getType();
       
   196 				TraceCompilerException exception = new TraceCompilerException(
       
   197 						TraceCompilerErrorCode.INVALID_PARAMETER_TYPE,
       
   198 						params, param.getSourceLocation());
       
   199 				TraceCompilerEngineGlobals.getEvents().postError(
       
   200 						exception);
       
   201 			}
       
   202 		} else {
       
   203 			parameter = createParameter(owner, param, foundTable);
       
   204 		}
       
   205 		return parameter;
       
   206 	}
       
   207 
       
   208 	/**
       
   209 	 * Processes a non-void parameter type that was not associated with a
       
   210 	 * constant table
       
   211 	 * 
       
   212 	 * @param owner
       
   213 	 *            the owner for the parameter
       
   214 	 * @param param
       
   215 	 *            the parameter found from source
       
   216 	 * @param type
       
   217 	 *            the parameter type as parsed by source package
       
   218 	 * @return the parameter
       
   219 	 */
       
   220 	private TraceParameter createParameter(Trace owner, SourceParameter param,
       
   221 			TypeMapping type) {
       
   222 		String name = param.getName();
       
   223 		TraceParameter retval = null;
       
   224 		if (name == null || name.length() == 0) {
       
   225 			String s = TraceCompilerEngineErrorMessages.getErrorMessage(
       
   226 					TraceCompilerErrorCode.EMPTY_PARAMETER_NAME, null);
       
   227 			TraceCompilerEngineGlobals.getEvents().postWarningMessage(s,
       
   228 					param.getSourceLocation());
       
   229 		} else {
       
   230 			try {
       
   231 				retval = RuleUtils.createParameterFromType(owner, name, type);
       
   232 				if (retval != null && type.valueToPointer) {
       
   233 					// Posts a warning about value-to-pointer conversion
       
   234 					TraceCompilerEngineGlobals.getEvents()
       
   235 							.postWarningMessage(VALUE_TO_POINTER_WARNING,
       
   236 									param.getSourceLocation());
       
   237 				}
       
   238 			} catch (TraceCompilerException e) {
       
   239 				// Changes the source of the error to the location that failed
       
   240 				TraceCompilerException exception = new TraceCompilerException(e.getErrorCode(), e
       
   241 						.getErrorParameters(), param
       
   242 						.getSourceLocation());
       
   243 				TraceCompilerEngineGlobals.getEvents().postError(
       
   244 						exception);
       
   245 			}
       
   246 		}
       
   247 		return retval;
       
   248 	}
       
   249 
       
   250 	/**
       
   251 	 * Processes a non-void parameter type that was associated with a constant
       
   252 	 * table
       
   253 	 * 
       
   254 	 * @param owner
       
   255 	 *            the owner for the parameter
       
   256 	 * @param param
       
   257 	 *            the parameter found from source
       
   258 	 * @param table
       
   259 	 *            the constant table the parameter was associated to
       
   260 	 * @return the parameter
       
   261 	 */
       
   262 	private TraceParameter createParameter(Trace owner, SourceParameter param,
       
   263 			TraceConstantTable table) {
       
   264 		String name = param.getName();
       
   265 		TraceParameter retval = null;
       
   266 		if (name == null || name.length() == 0) {
       
   267 			String s = TraceCompilerEngineErrorMessages.getErrorMessage(
       
   268 					TraceCompilerErrorCode.EMPTY_PARAMETER_NAME, null);
       
   269 			TraceCompilerEngineGlobals.getEvents().postWarningMessage(s,
       
   270 					param.getSourceLocation());
       
   271 		} else {
       
   272 			try {
       
   273 				retval = RuleUtils.createParameterFromConstantTable(owner,
       
   274 						name, table);
       
   275 			} catch (TraceCompilerException e) {
       
   276 				// Changes the source of the error to the location that failed
       
   277 				TraceCompilerException exception = new TraceCompilerException(e.getErrorCode(), e
       
   278 						.getErrorParameters(), param
       
   279 						.getSourceLocation());
       
   280 				TraceCompilerEngineGlobals.getEvents().postError(
       
   281 						exception);
       
   282 			}
       
   283 		}
       
   284 		return retval;
       
   285 	}
       
   286 
       
   287 	/*
       
   288 	 * (non-Javadoc)
       
   289 	 * 
       
   290 	 * @see
       
   291 	 * com.nokia.tracecompiler.model.TraceObjectRuleRemoveOnCreate#canBeRemoved()
       
   292 	 */
       
   293 	public boolean canBeRemoved() {
       
   294 		// This is not copied to exit trace -> Can be removed
       
   295 		return true;
       
   296 	}
       
   297 
       
   298 }